From e45f88c426506615f1815279c428cc3b039efe70 Mon Sep 17 00:00:00 2001 From: Taneem Ibrahim Date: Fri, 15 Sep 2023 12:55:39 -0500 Subject: [PATCH 001/254] Initial commit --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 1 + 2 files changed, 202 insertions(+) create mode 100644 LICENSE create mode 100644 README.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed 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. diff --git a/README.md b/README.md new file mode 100644 index 00000000..ac92625f --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# model-registry \ No newline at end of file From e355fc9d4e264ef5030300b11255823f3381beb5 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 30 Aug 2023 16:47:00 -0700 Subject: [PATCH 002/254] Initial Version --- .gitignore | 5 + Dockerfile | 1 + Makefile | 19 + cmd/root.go | 90 + cmd/serve.go | 139 ++ go.mod | 39 + go.sum | 517 ++++++ main.go | 22 + ml_metadata/proto/metadata_source.proto | 760 ++++++++ ml_metadata/proto/metadata_store.proto | 1234 +++++++++++++ .../proto/metadata_store_service.proto | 1525 +++++++++++++++++ model/db/artifact.gen.go | 24 + model/db/artifactproperty.gen.go | 25 + model/db/association.gen.go | 19 + model/db/attribution.gen.go | 19 + model/db/context.gen.go | 22 + model/db/contextproperty.gen.go | 25 + model/db/event.gen.go | 21 + model/db/eventpath.gen.go | 20 + model/db/execution.gen.go | 23 + model/db/executionproperty.gen.go | 25 + model/db/mlmdenv.gen.go | 17 + model/db/parentcontext.gen.go | 18 + model/db/parenttype.gen.go | 18 + model/db/type.gen.go | 24 + model/db/typeproperty.gen.go | 19 + server/db_context.go | 65 + server/grpc_server.go | 447 +++++ test/python/test_mlmetadata.py | 146 ++ 29 files changed, 5328 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 cmd/root.go create mode 100644 cmd/serve.go create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 ml_metadata/proto/metadata_source.proto create mode 100644 ml_metadata/proto/metadata_store.proto create mode 100644 ml_metadata/proto/metadata_store_service.proto create mode 100644 model/db/artifact.gen.go create mode 100644 model/db/artifactproperty.gen.go create mode 100644 model/db/association.gen.go create mode 100644 model/db/attribution.gen.go create mode 100644 model/db/context.gen.go create mode 100644 model/db/contextproperty.gen.go create mode 100644 model/db/event.gen.go create mode 100644 model/db/eventpath.gen.go create mode 100644 model/db/execution.gen.go create mode 100644 model/db/executionproperty.gen.go create mode 100644 model/db/mlmdenv.gen.go create mode 100644 model/db/parentcontext.gen.go create mode 100644 model/db/parenttype.gen.go create mode 100644 model/db/type.gen.go create mode 100644 model/db/typeproperty.gen.go create mode 100644 server/db_context.go create mode 100644 server/grpc_server.go create mode 100644 test/python/test_mlmetadata.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..81668d33 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea +.ml-metadata-go-server.yaml +ml-metadata-go-server +ml_metadata/proto/*.go +metadata.sqlite.db diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..c24d5ef7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1 @@ +FROM \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..00e39e4a --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +gen/grpc: ml_metadata/proto/*.proto + protoc --go_out=. --go_opt=paths=source_relative \ + --go-grpc_out=. --go-grpc_opt=paths=source_relative \ + ml_metadata/proto/metadata_store.proto ml_metadata/proto/metadata_store_service.proto + +clean: + rm -Rf ml_metadata/*.go + +build: gen/grpc + go build + +run/server: gen/grpc + go run main.go serve + +run/client: gen/grpc + python3.9 test/python/test_mlmetadata.py + +serve: build + ./ml-metadata-go-server serve diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 00000000..c21b05ad --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,90 @@ +/* +Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com + +Licensed 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 cmd + +import ( + "fmt" + "log" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var cfgFile string + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "ml-metadata-go-server", + Short: "A brief description of your application", + Long: `A longer description that spans multiple lines and likely contains +examples and usage of using your application. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + log.Fatalf("error: %v", err) + os.Exit(1) + } +} + +func init() { + cobra.OnInitialize(initConfig) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ml-metadata-go-server.yaml)") + + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := os.UserHomeDir() + cobra.CheckErr(err) + + // Search config in home directory with name ".ml-metadata-go-server" (without extension). + viper.AddConfigPath(home) + viper.SetConfigType("yaml") + viper.SetConfigName(".ml-metadata-go-server") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + } +} diff --git a/cmd/serve.go b/cmd/serve.go new file mode 100644 index 00000000..4e88ee16 --- /dev/null +++ b/cmd/serve.go @@ -0,0 +1,139 @@ +/* +Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com + +Licensed 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 cmd + +import ( + "context" + "fmt" + "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" + "github.com/dhirajsb/ml-metadata-go-server/server" + "github.com/golang/glog" + "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" + "github.com/spf13/cobra" + "google.golang.org/grpc" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "log" + "net" + "os" + "sync" +) + +func InterceptorLogger(l *log.Logger) logging.Logger { + return logging.LoggerFunc(func(_ context.Context, lvl logging.Level, msg string, fields ...any) { + switch lvl { + case logging.LevelDebug: + msg = fmt.Sprintf("DEBUG :%v", msg) + case logging.LevelInfo: + msg = fmt.Sprintf("INFO :%v", msg) + case logging.LevelWarn: + msg = fmt.Sprintf("WARN :%v", msg) + case logging.LevelError: + msg = fmt.Sprintf("ERROR :%v", msg) + default: + panic(fmt.Sprintf("unknown level %v", lvl)) + } + l.Println(append([]any{"msg", msg}, fields...)) + }) +} + +var ( + dbFile string + grpcHost = "localhost" + grpcPort int = 8080 + + // serveCmd represents the serve command + serveCmd = &cobra.Command{ + Use: "serve", + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("serve called") + + // connect to the DB using Gorm + db, err := NewDatabaseConnection(dbFile) + if err != nil { + log.Fatalf("db connection failed: %v", err) + } + + // serve the grpc server + listen, err := net.Listen("tcp", fmt.Sprintf("%s:%d", grpcHost, grpcPort)) + if err != nil { + log.Fatalf("grpc listen failed: %v", err) + } + // TODO map server options from flags + logger := log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile) + lopts := []logging.Option{ + logging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent, logging.StartCall, logging.FinishCall), + // Add any other option (check functions starting with logging.With). + } + opts := []grpc.ServerOption{ + grpc.ChainUnaryInterceptor( + logging.UnaryServerInterceptor(InterceptorLogger(logger), lopts...), + ), + grpc.ChainStreamInterceptor( + logging.StreamServerInterceptor(InterceptorLogger(logger), lopts...), + ), + } + + grpcServer := grpc.NewServer(opts...) + proto.RegisterMetadataStoreServiceServer(grpcServer, server.NewGrpcServer(db)) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + glog.Info("Starting grpc server...") + err = grpcServer.Serve(listen) + if err != nil { + log.Fatalf("grpc serving failed: %v", err) + } + wg.Done() + }() + + // TODO serve the GraphQL server + + // wait for servers to finish + wg.Wait() + + return nil + }, + } +) + +func NewDatabaseConnection(dbFile string) (*gorm.DB, error) { + return gorm.Open(sqlite.Open(dbFile), &gorm.Config{}) +} + +func init() { + rootCmd.AddCommand(serveCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // serveCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + serveCmd.Flags().StringVar(&dbFile, "db-file", "metadata.sqlite.db", "Sqlite DB file") + serveCmd.Flags().StringVar(&grpcHost, "grpc-host", grpcHost, "gRPC listen hostname") + serveCmd.Flags().IntVar(&grpcPort, "grpc-port", grpcPort, "gRPC listen port") +} diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..de5b1c8d --- /dev/null +++ b/go.mod @@ -0,0 +1,39 @@ +module github.com/dhirajsb/ml-metadata-go-server + +go 1.19 + +require ( + github.com/golang/glog v1.1.0 + github.com/golang/protobuf v1.5.3 + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 + github.com/spf13/cobra v1.7.0 + github.com/spf13/viper v1.16.0 + google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d + google.golang.org/grpc v1.57.0 + google.golang.org/protobuf v1.31.0 + gorm.io/driver/sqlite v1.5.3 + gorm.io/gorm v1.25.4 +) + +require ( + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-sqlite3 v1.14.17 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..c97e0669 --- /dev/null +++ b/go.sum @@ -0,0 +1,517 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 h1:2cz5kSrxzMYHiWOBbKj8itQm+nRykkB8aMv4ThcHYHA= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= +google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/sqlite v1.5.3 h1:7/0dUgX28KAcopdfbRWWl68Rflh6osa4rDh+m51KL2g= +gorm.io/driver/sqlite v1.5.3/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= +gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= +gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/main.go b/main.go new file mode 100644 index 00000000..c1f1a032 --- /dev/null +++ b/main.go @@ -0,0 +1,22 @@ +/* +Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com + +Licensed 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 main + +import "github.com/dhirajsb/ml-metadata-go-server/cmd" + +func main() { + cmd.Execute() +} diff --git a/ml_metadata/proto/metadata_source.proto b/ml_metadata/proto/metadata_source.proto new file mode 100644 index 00000000..3fc8584c --- /dev/null +++ b/ml_metadata/proto/metadata_source.proto @@ -0,0 +1,760 @@ +/* Copyright 2019 Google LLC + +Licensed 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 + + https://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. +==============================================================================*/ +// The returned results from a MetadataSource. +syntax = "proto3"; +option go_package = "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto"; + +package ml_metadata; + +import "google/protobuf/any.proto"; + +// A collection of returned records. +message RecordSet { + // An individual record (e.g., row) returned by a MetadataSource. + // The record does not address the type conversion. + message Record { + repeated string values = 1; + } + + // index-aligned column names for all records + repeated string column_names = 1; + + // a list of records returned by a query + repeated Record records = 2; +} + +// Contains supported metadata sources types in MetadataAccessObject. +// Next index: 7 +enum MetadataSourceType { + UNKNOWN_METADATA_SOURCE = 0; + // a fake in memory metadata_source for testing + // DEPRECATED -- use SQLITE_METADATA_SOURCE instead. + FAKE_METADATA_SOURCE = 1; + // a MYSQL metadata source. + MYSQL_METADATA_SOURCE = 2; + // A Sqlite metadata source. + SQLITE_METADATA_SOURCE = 3; + // PostgreSQL, the index number is related to ConnectionConfig. + POSTGRESQL_METADATA_SOURCE = 6; + +} + +// A config includes a set of SQL queries and the type of metadata source. +// It is used by MetadataAccessObject to init backend and issue queries. +// Next ID: 144 +message MetadataSourceQueryConfig { + // the type of the metadata source + MetadataSourceType metadata_source_type = 1; + + // Template of a SQL query, which can contain parameterized variables using + // $0, $1, ... $9. + // For instance: + // query: "select * from foo where bar = $0" + // parameter_num: 1 + message TemplateQuery { + string query = 1; + int32 parameter_num = 2; + } + + // Below is a list of SQL templates queries required for MetadataAccessObject. + // The given SQL should follow conventions in a metadata_source_type. + + // Drops the Type table. + TemplateQuery drop_type_table = 3; + + // Creates the Type table. + TemplateQuery create_type_table = 4; + + // Checks the existence of the Type table. + TemplateQuery check_type_table = 44; + + // Inserts an artifact type into the Type table. It has 3 parameters. + // $0 is the name + // $1 is the version + // $2 is the description + TemplateQuery insert_artifact_type = 54; + + // Inserts an execution type into the Type table. It has 3 parameters. + // $0 is the type name + // $1 is the version + // $2 is the description + // $3 is the input_type serialized as JSON or null. + // $4 is the output_type serialized as JSON or null. + TemplateQuery insert_execution_type = 55; + + // Inserts a context type into the Type table. It has 1 parameter. + // $0 is the type name + // $1 is the version + // $2 is the description + TemplateQuery insert_context_type = 58; + + // Queries types by a list of type ids. It has 2 parameter. + // $0 is the type_ids + // $1 is the is_artifact_type + TemplateQuery select_types_by_id = 128; + + // Queries types by a list of external ids. + // It has 2 parameters. + // $0 is the external_ids + // $1 is the type_kind + TemplateQuery select_types_by_external_ids = 134; + + // Queries a type by its type id. It has 2 parameters. + // $0 is the type id + // $1 is the is_artifact_type + TemplateQuery select_type_by_id = 6; + + // Queries a type by its type name. It has 2 parameters. + // $0 is the type name + // $1 is the type_kind + TemplateQuery select_type_by_name = 20; + + // Queries a type by its type name and version. It has 3 parameters. + // $0 is the type name + // $1 is the type version + // $2 is the type_kind + TemplateQuery select_type_by_name_and_version = 111; + + // Queries types by a list of type names. + // It has 2 parameters. + // $0 is the type names + // $1 is the type kind + TemplateQuery select_types_by_names = 136; + + // Queries types by a list of type name and version pairs. + // It has 2 parameters. + // $0 is the type name and version pairs + // $1 is the type kind + TemplateQuery select_types_by_names_and_versions = 137; + + // Queries for all type instances. It has 1 parameter. + // $0 is the is_artifact_type + TemplateQuery select_all_types = 57; + + // Updates a type in the Type table. It has 2 parameters. + // $0 is the existing type id + // $1 is the external_id of the Type + TemplateQuery update_type = 138; + + // Drops the ParentType table. + TemplateQuery drop_parent_type_table = 99; + + // Creates the ParentType table. + TemplateQuery create_parent_type_table = 100; + + // Checks the existence of the ParentType table. + TemplateQuery check_parent_type_table = 101; + + // Inserts a parent type into the ParentType table. It has 2 parameters: + // $0 is the type_id + // $1 is the parent_type_id + TemplateQuery insert_parent_type = 109; + + // Queries parent types from the ParentType table by type_id. + // It has 1 parameter. + // $0 is the type_id + TemplateQuery select_parent_type_by_type_id = 110; + + // Drops the TypeProperty table. + TemplateQuery drop_type_property_table = 7; + + // Creates the TypeProperty table. + TemplateQuery create_type_property_table = 8; + + // Checks the existence of the TypeProperty table. + TemplateQuery check_type_property_table = 45; + + // Inserts a property of a type into the TypeProperty table. It has 3 + // parameters. + // $0 is the type_id + // $1 is the name of the property + // $2 is the data_type of the property + TemplateQuery insert_type_property = 9; + + // Queries properties of a type from the TypeProperty table by the type_id + // Returns a list of properties (name, data_type). It has 1 parameter. + // $0 is the type_id + TemplateQuery select_property_by_type_id = 10; + + // Queries the last inserted id. + TemplateQuery select_last_insert_id = 11; + + // Drops the Artifact table. + TemplateQuery drop_artifact_table = 12; + + // Creates the Artifact table. + TemplateQuery create_artifact_table = 13; + + // Checks the existence of the Artifact table. + TemplateQuery check_artifact_table = 46; + + // Inserts an artifact into the Artifact table. It has 5 parameters. + // $0 is the type_id + // $1 is the uri of the Artifact + // $2 is the name of the Artifact + // $3 is the create_time_since_epoch of the Artifact + // $4 is the last_update_time_since_epoch of the Artifact + TemplateQuery insert_artifact = 14; + + // Queries an artifact from the Artifact table by its id. It has 1 parameter. + // $0 is the artifact_id + TemplateQuery select_artifact_by_id = 15; + + // Queries an artifact from the Artifact table by its name and type id. + // It has 2 parameter. + // $0 is the type_id + // $1 is the name of the Artifact + TemplateQuery select_artifact_by_type_id_and_name = 94; + + // Queries an artifact from the Artifact table by its type_id. It has 1 + // parameter. + // $0 is the artifact_type_id + TemplateQuery select_artifacts_by_type_id = 52; + + // Queries an artifact from the Artifact table by its uri. It has 1 parameter. + // $0 is the uri + TemplateQuery select_artifacts_by_uri = 56; + + // Queries artifacts from the Artifact table by + // external_ids. It has 1 parameter. $0 is the external_ids + TemplateQuery select_artifacts_by_external_ids = 130; + + // Updates an artifact in the Artifact table. It has 4 parameters. + // $0 is the existing artifact id + // $1 is the type_id + // $2 is the uri of the Artifact + // $3 is the last_update_time_since_epoch of the Artifact + TemplateQuery update_artifact = 21; + + // Drops the ArtifactProperty table. + TemplateQuery drop_artifact_property_table = 16; + + // Creates the ArtifactProperty table. + TemplateQuery create_artifact_property_table = 17; + + // Checks the existence of the ArtifactProperty table. + TemplateQuery check_artifact_property_table = 47; + + // Insert a property of an artifact from the ArtifactProperty table. It has 5 + // parameters. + // $0 is the property data type + // $1 is the artifact_id + // $2 is the name of the artifact property + // $3 is the flag to indicate whether it is a custom property + // $4 is the value of the property + TemplateQuery insert_artifact_property = 18; + + // Queries properties of an artifact from the ArtifactProperty table by the + // artifact id. It has 1 parameter. + // $0 is the artifact_id + TemplateQuery select_artifact_property_by_artifact_id = 19; + + // Updates a property of an artifact in the ArtifactProperty table. It has 4 + // parameters. + // $0 is the property data type + // $1 is the value of the property + // $2 is the artifact_id + // $3 is the name of the artifact property + TemplateQuery update_artifact_property = 22; + + // Deletes a property of an artifact. It has 2 parameters. + // $0 is the artifact_id + // $1 is the name of the artifact property + TemplateQuery delete_artifact_property = 23; + + // Drops the Execution table. + TemplateQuery drop_execution_table = 24; + + // Creates the Execution table. + TemplateQuery create_execution_table = 25; + + // Checks the existence of the Execution table. + TemplateQuery check_execution_table = 48; + + // Inserts an execution into the Execution table. It has 4 parameter. + // $0 is the type_id + // $1 is the name of the execution + // $2 is the create_time_since_epoch of the execution + // $3 is the last_update_time_since_epoch of the execution + TemplateQuery insert_execution = 28; + + // Queries an execution from the Execution table by its id. It has 1 + // parameter. + // $0 is the execution_id + TemplateQuery select_execution_by_id = 29; + + // Queries an execution from the Execution table by its name and type id. + // It has 2 parameters. + // $0 is the type_id + // $1 is the name + TemplateQuery select_execution_by_type_id_and_name = 95; + + // Queries an execution from the Execution table by its type_id. It has 1 + // parameter. + // $0 is the execution_type_id + TemplateQuery select_executions_by_type_id = 53; + + // Queries executions from the Execution table by external_ids. + // It has 1 parameter. + // $0 is the external_ids + TemplateQuery select_executions_by_external_ids = 132; + + // Updates an execution in the Execution table. It has 3 parameters. + // $0 is the existing execution id + // $1 is the type_id + // $2 is the last_update_time_since_epoch of the execution + TemplateQuery update_execution = 34; + + // Drops the ExecutionProperty table. + TemplateQuery drop_execution_property_table = 26; + + // Creates the ExecutionProperty table. + TemplateQuery create_execution_property_table = 27; + + // Checks the existence of the ExecutionProperty table. + TemplateQuery check_execution_property_table = 49; + + // Insert a property of an execution from the ExecutionProperty table. It has + // 5 parameters. + // $0 is the property data type + // $1 is the execution_id + // $2 is the name of the execution property + // $3 is the flag to indicate whether it is a custom property + // $4 is the value of the property + TemplateQuery insert_execution_property = 30; + + // Queries properties of an execution from the ExecutionProperty table by the + // execution id. It has 1 parameter. + // $0 is the execution_id + TemplateQuery select_execution_property_by_execution_id = 31; + + // Updates a property of an execution in the ExecutionProperty table. It has 4 + // parameters. + // $0 is the property data type + // $1 is the value of the property + // $2 is the execution_id + // $3 is the name of the execution property + TemplateQuery update_execution_property = 32; + + // Deletes a property of an execution. It has 2 parameters. + // $0 is the execution_id + // $1 is the name of the execution property + TemplateQuery delete_execution_property = 33; + + // Drops the Context table. + TemplateQuery drop_context_table = 67; + + // Creates the Context table. + TemplateQuery create_context_table = 68; + + // Checks the existence of the Context table. + TemplateQuery check_context_table = 69; + + // Inserts a context into the Context table. It has 4 parameters. + // $0 is the type_id + // $1 is the name of the Context + // $2 is the create_time_since_epoch of the Context + // $3 is the last_update_time_since_epoch of the Context + TemplateQuery insert_context = 70; + + // Queries a context from the Context table by its id. It has 1 parameter. + // $0 is the context_id + TemplateQuery select_context_by_id = 71; + + // Queries a context from the Context table by its type_id. It has 1 + // parameter. + // $0 is the context_type_id + TemplateQuery select_contexts_by_type_id = 72; + + // Queries a context from the Context table by its type_id and name. It has 2 + // parameters. + // $0 is the context_type_id + // $1 is the context_name + TemplateQuery select_context_by_type_id_and_name = 93; + + // Queries contexts from the Context table by external_ids. + // It has 1 parameter. + // $0 is the external_ids + TemplateQuery select_contexts_by_external_ids = 133; + + // Updates a context in the Context table. It has 4 parameters. + // $0 is the existing context id + // $1 is the type_id + // $2 is the name of the Context + // $3 is the last_update_time_since_epoch of the Context + TemplateQuery update_context = 73; + + // Drops the ContextProperty table. + TemplateQuery drop_context_property_table = 74; + + // Creates the ContextProperty table. + TemplateQuery create_context_property_table = 75; + + // Checks the existence of the ContextProperty table. + TemplateQuery check_context_property_table = 76; + + // Insert a property of a context from the ContextProperty table. It has 5 + // parameters. + // $0 is the property data type + // $1 is the context_id + // $2 is the name of the context property + // $3 is the flag to indicate whether it is a custom property + // $4 is the value of the property + TemplateQuery insert_context_property = 77; + + // Queries properties of a context from the ContextProperty table by the + // context id. It has 1 parameter. + // $0 is the context_id + TemplateQuery select_context_property_by_context_id = 78; + + // Updates a property of a context in the ContextProperty table. It has 4 + // parameters. + // $0 is the property data type + // $1 is the value of the property + // $2 is the context_id + // $3 is the name of the context property + TemplateQuery update_context_property = 79; + + // Deletes a property of a context. It has 2 parameters. + // $0 is the context_id + // $1 is the name of the context property + TemplateQuery delete_context_property = 80; + + // Drops the ParentContext table. + TemplateQuery drop_parent_context_table = 102; + + // Creates the ParentContext table. + TemplateQuery create_parent_context_table = 103; + + // Checks the existence of the ParentContext table. + TemplateQuery check_parent_context_table = 104; + + // Inserts a parent context into the ParentContext table. It has 2 parameters: + // $0 is the context_id + // $1 is the parent_context_id + TemplateQuery insert_parent_context = 106; + + // Queries parent contexts from the ParentContext table by context_id. + // It has 1 parameter. + // $0 is the context_id + TemplateQuery select_parent_context_by_context_id = 107; + + // Queries parent contexts from the ParentContext table by parent_context_id. + // It has 1 parameter. + // $0 is the parent_context_id + TemplateQuery select_parent_context_by_parent_context_id = 108; + + // Queries parent contexts from the ParentContext table by context_ids. + // It has 1 parameter. + // $0 is the context_ids + TemplateQuery select_parent_contexts_by_context_ids = 139; + + // Queries parent contexts from the ParentContext table by parent_context_ids. + // It has 1 parameter. + // $0 is the parent_context_ids + TemplateQuery select_parent_contexts_by_parent_context_ids = 140; + + // Drops the Event table. + TemplateQuery drop_event_table = 35; + + // Creates the Event table. + TemplateQuery create_event_table = 36; + + // Checks the existence of the Event table. + TemplateQuery check_event_table = 50; + + // Inserts an event into the Event table. It has 4 parameters. + // $0 is the artifact_id + // $1 is the execution_id + // $2 is the event type + // $3 is the event time + TemplateQuery insert_event = 37; + + // Queries events from the Event table by a collection of artifact ids. It has + // 1 parameter. + // $0 is the collection string of artifact ids joined by ", ". + TemplateQuery select_event_by_artifact_ids = 96; + + // Queries events from the Event table by a collection of execution ids. It + // has 1 parameter. + // $0 is the collection string of execution ids joined by ", ". + TemplateQuery select_event_by_execution_ids = 97; + + // Drops the EventPath table. + TemplateQuery drop_event_path_table = 40; + + // Creates the EventPath table. + TemplateQuery create_event_path_table = 41; + + // Checks the existence of the EventPath table. + TemplateQuery check_event_path_table = 51; + + // Inserts a path into the EventPath table. It has 4 parameters + // $0 is the event_id + // $1 is the step value case, either index or key + // $2 is the is_index_step indicates the step value case + // $3 is the value of the step + TemplateQuery insert_event_path = 42; + + // Queries paths from the EventPath table by a collection of event ids. It has + // 1 parameter. + // $0 is the collection string of event ids joined by ", ". + TemplateQuery select_event_path_by_event_ids = 98; + + // Drops the Association table. + TemplateQuery drop_association_table = 81; + + // Creates the Association table. + TemplateQuery create_association_table = 82; + + // Checks the existence of the Association table. + TemplateQuery check_association_table = 83; + + // Inserts an association into the Association table. It has 2 parameters. + // $0 is the context_id + // $1 is the execution_id + TemplateQuery insert_association = 84; + + // Queries association from the Association table by its context id. + // It has 1 parameter. + // $0 is the context_id + TemplateQuery select_association_by_context_id = 85; + + reserved 86; + + // Queries associations from the Association table by execution ids. + // It has 1 parameter. + // $0 are the execution_ids. + TemplateQuery select_associations_by_execution_ids = 142; + + // Drops the Attribution table. + TemplateQuery drop_attribution_table = 87; + + // Creates the Attribution table. + TemplateQuery create_attribution_table = 88; + + // Checks the existence of the Attribution table. + TemplateQuery check_attribution_table = 89; + + // Inserts an attribution into the Attribution table. It has 2 parameters. + // $0 is the context_id + // $1 is the artifact_id + TemplateQuery insert_attribution = 90; + + // Queries attribution from the Attribution table by its context id. + // It has 1 parameter. + // $0 is the context_id + TemplateQuery select_attribution_by_context_id = 91; + + reserved 92; + + // Queries attributions from the Attribution table by artifact ids. + // It has 1 parameter. + // $0 are the artifact_ids. + TemplateQuery select_attributions_by_artifact_ids = 143; + + // Drops the MLMDEnv table. + TemplateQuery drop_mlmd_env_table = 60; + + // Creates the MLMDEnv table. + TemplateQuery create_mlmd_env_table = 61; + + // Below is a list of fields required for metadata source migrations when + // the library being used having different versions from a pre-exist database. + + // The version of the current query config. Increase the version by 1 in any + // CL that includes physical schema changes and provides a migration function + // that uses a list migration queries. The database stores it to indicate the + // current database version. When metadata source creates, it compares the + // given `schema_version` in query config with the `schema_version` stored in + // the database, and migrate the database if needed. + int64 schema_version = 59; + + // Checks the MLMDEnv table and query the schema version. + // At MLMD release v0.13.2, by default it is v0. + TemplateQuery check_mlmd_env_table = 63; + + // This query returns an int 0 or int 1 to indicate whether mlmdenv table + // and the corresponding schema exist. In contrast, check_mlmd_env_table + // will return the schema_version value directly, assuming mlmdenv table + // exists. The reason for this query is that PostgreSQL will abort transaction + // if a query inside that transaction fails, while other DB types do not + // abort the transaction. This query serves single purpose to check whether + // mlmdenv table exists, while check_mlmd_env_table serves two goals: table + // schema checking and query for MLMD schema version. + TemplateQuery check_mlmd_env_table_existence = 141; + + // Insert schema_version. + // $0 is the schema_version + TemplateQuery insert_schema_version = 66; + + // Update schema_version + // $0 is the schema_version + TemplateQuery update_schema_version = 64; + + // Check the database is a valid database produced by 0.13.2 MLMD release. + // The schema version and migration are introduced after that release. + TemplateQuery check_tables_in_v0_13_2 = 65; + + // A list of secondary indices to be applied on the current schema. This is + // intended for indices that cover multiple columns or which cannot be + // created as part of table DDL statements. + repeated TemplateQuery secondary_indices = 105; + + reserved 38, 39, 43; + + message DbVerification { + // Total number of MLMD tables. + int32 total_num_tables = 1; + // Total number of MLMD indexes. + int32 total_num_indexes = 2; + } + + // A migration scheme that is used by a migration function to transit a + // database at a schema_version to schema_version + 1. + // DDL is often metadata source specific, if provided, each metadata source + // should have its own setting. + message MigrationScheme { + // Sequence of queries to increase the schema version by 1. + repeated TemplateQuery upgrade_queries = 1; + + // Sequence of queries to decrease the schema version by 1. + repeated TemplateQuery downgrade_queries = 3; + + // For test purposes, it defines the setup query and post condition + // invariants of a migration scheme. + message VerificationScheme { + // This optional field defines the additional details of recreating: + // a) the schema of previous version, as the DDL queries will not be + // available in newer library versions. + // b) and/or the records of related tables which have schema changes. + // Note the setup queries is used in a sequence along with other migration + // schemes of previous version in order to test upgrading from all + // known previous versions to the library version. + repeated TemplateQuery previous_version_setup_queries = 1; + + // This optional field defines the verification queries, each of which + // returns only True/False in the select to assert the state transition + // invariant is the same, e.g., + // * conditions on number of rows + // * conditions on data model entities (e.g., type, artifact, property). + repeated TemplateQuery post_migration_verification_queries = 2; + } + + // Details of verifying the correctness of upgrade_queries. + VerificationScheme upgrade_verification = 2; + + // Details of verifying the correctness of downgrade_queries. + VerificationScheme downgrade_verification = 4; + + // Verification of the DB schema in this version. + DbVerification db_verification = 5; + } + + // Each metadata source should provides migration schemes, each of which + // defines the schema change details for a particular `schema_version` (sv_i). + // When a migration procedure wants to upgrade to sv_i, it looks for the + // MigrationScheme with sv_i as map key. + map migration_schemes = 62; + + // Deletes contexts by id. + // $0 are the context ids. + TemplateQuery delete_contexts_by_id = 112; + + // Deletes contexts properties by contexts ids. + // $0 are the context ids. + TemplateQuery delete_contexts_properties_by_contexts_id = 113; + + // Delete parent contexts by parent context ids. + // $0 are the parent context ids. + TemplateQuery delete_parent_contexts_by_parent_ids = 114; + + // Delete parent contexts by child context ids. + // $0 are the child context ids. + TemplateQuery delete_parent_contexts_by_child_ids = 115; + + // Delete parent contexts by parent context ids. + // $0 is the parent context id. + // $1 are the child context ids. + TemplateQuery delete_parent_contexts_by_parent_id_and_child_ids = 131; + + // Deletes artifacts by id. + // $0 are the artifact ids. + TemplateQuery delete_artifacts_by_id = 116; + + // Deletes artifacts properties by artifacts ids. + // $0 are the artifact ids. + TemplateQuery delete_artifacts_properties_by_artifacts_id = 117; + + // Deletes executions by id. + // $0 are the execution ids. + TemplateQuery delete_executions_by_id = 118; + + // Deletes executions properties by executions ids. + // $0 are the execution ids. + TemplateQuery delete_executions_properties_by_executions_id = 119; + + // Delete events by artifact ids. + // $0 are the artifact ids. + TemplateQuery delete_events_by_artifacts_id = 120; + + // Delete events by execution ids. + // $0 are the execution ids. + TemplateQuery delete_events_by_executions_id = 121; + + // Delete associations by context ids. + // $0 are the context ids. + TemplateQuery delete_associations_by_contexts_id = 122; + + // Delete associations by execution ids. + // $0 are the context ids. + TemplateQuery delete_associations_by_executions_id = 123; + + // Delete attributions by context ids. + // $0 are the context ids. + TemplateQuery delete_attributions_by_contexts_id = 124; + + // Delete attributions by artifact ids. + // $0 are the artifact ids. + TemplateQuery delete_attributions_by_artifacts_id = 125; + + // Delete event paths. This query cleans up event paths where + // the events do not exist. + TemplateQuery delete_event_paths = 126; + + // Delete a parent type from the ParentType table. It has 2 parameters: + // $0 is the type_id + // $1 is the parent_type_id + TemplateQuery delete_parent_type = 127; + + // Queries properties of a list of types from the TypeProperty table by + // `type_ids`. + // Returns a list of properties(type_id, name, data_type).It has 1 parameter: + // $0 is the type_ids + TemplateQuery select_properties_by_type_id = 129; + + // Allows different MetadataSourceTypes to configure its own options when + // creating MetadataAccessObject. + google.protobuf.Any metadata_source_type_specific_options = 135; +} + + +// A payload that can be optionally attached to absl::Status messages to +// indicate failure specific information like error codes for MySQL based +// backends. +message MySQLSourceErrorInfo { + // Error code for the error. + int64 mysql_error_code = 1; +} diff --git a/ml_metadata/proto/metadata_store.proto b/ml_metadata/proto/metadata_store.proto new file mode 100644 index 00000000..c7fddb3d --- /dev/null +++ b/ml_metadata/proto/metadata_store.proto @@ -0,0 +1,1234 @@ +/* Copyright 2019 Google LLC + +Licensed 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 + + https://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. +==============================================================================*/ +syntax = "proto2"; +option go_package = "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto"; + +package ml_metadata; + +import "google/protobuf/any.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/descriptor.proto"; + +extend google.protobuf.EnumValueOptions { + // The system type information of each simple type enum refers to. + optional SystemTypeExtension system_type_extension = 384560917; +} + +message SystemTypeExtension { + // The name of a system defined type. + optional string type_name = 1; +} + +// A value in properties. +message Value { + oneof value { + int64 int_value = 1; + double double_value = 2; + string string_value = 3; + google.protobuf.Struct struct_value = 4; + google.protobuf.Any proto_value = 5; + bool bool_value = 6; + } +} + +message Artifact { + // Output only. The unique server generated id of the artifact. + optional int64 id = 1; + // The client provided name of the artifact. This field is optional. If set, + // it must be unique among all the artifacts of the same artifact type within + // a database instance and cannot be changed once set. + optional string name = 7; + // The id of an ArtifactType. This needs to be specified when an artifact is + // created, and it cannot be changed. + optional int64 type_id = 2; + // Output only. The name of an ArtifactType. + optional string type = 8; + // The uniform resource identifier of the physical artifact. + // May be empty if there is no physical artifact. + optional string uri = 3; + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all artifacts within a database instance. + optional string external_id = 11; + // Properties of the artifact. + // Properties must be specified in the ArtifactType. + map properties = 4; + // User provided custom properties which are not defined by its type. + map custom_properties = 5; + + enum State { + UNKNOWN = 0; + // A state indicating that the artifact may exist. + PENDING = 1; + // A state indicating that the artifact should exist, unless something + // external to the system deletes it. + LIVE = 2; + // A state indicating that the artifact should be deleted. + MARKED_FOR_DELETION = 3; + // A state indicating that the artifact has been deleted. + DELETED = 4; + // A state indicating that the artifact has been abandoned, which may be + // due to a failed or cancelled execution. + ABANDONED = 5; + // A state indicating that the artifact is a reference artifact. At + // execution start time, the orchestrator produces an output artifact for + // each output key with state PENDING. However, for an intermediate + // artifact, this first artifact's state will be REFERENCE. Intermediate + // artifacts emitted during a component's execution will copy the REFERENCE + // artifact's attributes. At the end of an execution, the artifact state + // should remain REFERENCE instead of being changed to LIVE. + REFERENCE = 6; + } + + // The state of the artifact known to the system. + optional State state = 6; + // Output only. Create time of the artifact in millisecond since epoch. + optional int64 create_time_since_epoch = 9; + // Output only. Last update time of the artifact since epoch in millisecond + // since epoch. + optional int64 last_update_time_since_epoch = 10; + + // Output only. + optional google.protobuf.Any system_metadata = 12; +} + +// The list of supported property value types. +enum PropertyType { + UNKNOWN = 0; + INT = 1; + DOUBLE = 2; + STRING = 3; + // Prefer to use `PROTO` to store structed data since this option has + // inefficient database storage usage. + STRUCT = 4; + PROTO = 5; + BOOLEAN = 6; +} + +message ArtifactType { + // The id of the type. 1-1 relationship between type names and IDs. + optional int64 id = 1; + // The name of the type. It must be unique among ArtifactTypes within a + // database instance. + optional string name = 2; + // An optional version of the type. An empty string is treated as unset. + optional string version = 4; + // An optional description about the type. + optional string description = 5; + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all artifact types within a database + // instance. + optional string external_id = 7; + // The schema of the type. + // Properties are always optional in the artifact. + // Properties of an artifact type can be expanded but not contracted (i.e., + // you can add columns but not remove them). + map properties = 3; + + // An enum of system-defined artifact types. + enum SystemDefinedBaseType { + UNSET = 0 [(system_type_extension).type_name = 'unset_artifact_type']; + DATASET = 1 [(system_type_extension).type_name = 'mlmd.Dataset']; + MODEL = 2 [(system_type_extension).type_name = 'mlmd.Model']; + METRICS = 3 [(system_type_extension).type_name = 'mlmd.Metrics']; + STATISTICS = 4 [(system_type_extension).type_name = 'mlmd.Statistics']; + } + + // An optional system defined base_type expressing the intent of the current + // type. This field is useful for the tool builders to utilize the stored MLMD + // information, e.g., `MyModel` ArtifactType could set base_type = MODEL. + optional SystemDefinedBaseType base_type = 6; +} + +// An event represents a relationship between an artifact and an execution. +// There are different kinds of events, relating to both input and output, as +// well as how they are used by the mlmd powered system. +// For example, the DECLARED_INPUT and DECLARED_OUTPUT events are part of the +// signature of an execution. For example, consider: +// +// my_result = my_execution({"data":[3,7],"schema":8}) +// +// Where 3, 7, and 8 are artifact_ids, Assuming execution_id of my_execution is +// 12 and artifact_id of my_result is 15, the events are: +// { +// artifact_id:3, +// execution_id: 12, +// type:DECLARED_INPUT, +// path:{step:[{"key":"data"},{"index":0}]} +// } +// { +// artifact_id:7, +// execution_id: 12, +// type:DECLARED_INPUT, +// path:{step:[{"key":"data"},{"index":1}]} +// } +// { +// artifact_id:8, +// execution_id: 12, +// type:DECLARED_INPUT, +// path:{step:[{"key":"schema"}]} +// } +// { +// artifact_id:15, +// execution_id: 12, +// type:DECLARED_OUTPUT, +// path:{step:[{"key":"my_result"}]} +// } +// +// Other event types include INPUT/OUTPUT, INTERNAL_INPUT/_OUTPUT and +// PENDING_OUTPUT: +// +// * The INPUT/OUTPUT is an event that actually reads/writes an artifact by an +// execution. The input/output artifacts may not declared in the signature, +// For example, the trainer may output multiple caches of the parameters +// (as an OUTPUT), then finally write the SavedModel as a DECLARED_OUTPUT. +// +// * The INTERNAL_INPUT/_OUTPUT are event types which are only meaningful to +// an orchestration system to keep track of the details for later debugging. +// For example, a fork happened conditioning on an artifact, then an execution +// is triggered, such fork implementing may need to log the read and write +// of artifacts and may not be worth displaying to the users. +// +// For instance, in the above example, +// +// my_result = my_execution({"data":[3,7],"schema":8}) +// +// there is another execution (id: 15), which represents a +// `garbage_collection` step in an orchestration system +// +// gc_result = garbage_collection(my_result) +// +// that cleans `my_result` if needed. The details should be invisible to the +// end users and lineage tracking. The orchestrator can emit following events: +// +// { +// artifact_id: 15, +// execution_id: 15, +// type:INTERNAL_INPUT, +// } +// { +// artifact_id:16, // New artifact containing the GC job result. +// execution_id: 15, +// type:INTERNAL_OUTPUT, +// path:{step:[{"key":"gc_result"}]} +// } +// +// * The PENDING_OUTPUT event is used to indicate that an artifact is +// tentatively associated with an active execution which has not yet been +// finalized. For example, an orchestration system can register output +// artifacts of a running execution with PENDING_OUTPUT events to indicate +// the output artifacts the execution is expected to produce. When the +// execution is finished, the final set of output artifacts can be associated +// with the exeution using OUTPUT events, and any unused artifacts which were +// previously registered with PENDING_OUTPUT events can be updated to set +// their Artifact.State to ABANDONED. +// +// Events are unique of the same +// (artifact_id, execution_id, type) combination within a metadata store. +message Event { + // A simple path (e.g. {step{key:"foo"}}) can name an artifact in the context + // of an execution. + message Path { + message Step { + oneof value { + int64 index = 1; + string key = 2; + } + } + // A simple path (e.g. {step{key:"foo"}}) can name an artifact in the + // context of an execution. + repeated Step steps = 1; + } + // Events distinguish between an artifact that is written by the execution + // (possibly as a cache), versus artifacts that are part of the declared + // output of the Execution. For more information on what DECLARED_ means, + // see the comment on the message. + enum Type { + UNKNOWN = 0; + DECLARED_OUTPUT = 1; // A declared output of the execution. + DECLARED_INPUT = 2; // A declared input of the execution. + INPUT = 3; // An input of the execution. + OUTPUT = 4; // An output of the execution. + INTERNAL_INPUT = 5; // An internal input of the execution. + INTERNAL_OUTPUT = 6; // An internal output of the execution. + PENDING_OUTPUT = 7; // A pending output of the execution. + } + // The artifact id is required for an event, and should refer to an + // existing artifact. + optional int64 artifact_id = 1; + // The execution_id is required for an event, and should refer to an + // existing execution. + optional int64 execution_id = 2; + // The path in an artifact struct, or the name of an artifact. + optional Path path = 3; + // The type of an event. + optional Type type = 4; + // Time the event occurred + // Epoch is Jan 1, 1970, UTC + optional int64 milliseconds_since_epoch = 5; + + // Output only. + optional google.protobuf.Any system_metadata = 6; +} + +message Execution { + // Output only. The unique server generated id of the execution. + optional int64 id = 1; + // The client provided name of the execution. This field is optional. If set, + // it must be unique among all the executions of the same execution type + // within a database instance and cannot be changed once set. + optional string name = 6; + // The id of an ExecutionType. This needs to be specified when an execution is + // created, and it cannot be changed. + // The id of an ExecutionType. + optional int64 type_id = 2; + // Output only. The name of an ExecutionType. + optional string type = 7; + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all executions within a database instance. + optional string external_id = 10; + // The state of the Execution. The state transitions are + // NEW -> RUNNING -> COMPLETE | CACHED | FAILED | CANCELED + // CACHED means the execution is skipped due to cached results. + // CANCELED means the execution is skipped due to precondition not met. It is + // different from CACHED in that a CANCELED execution will not have any event + // associated with it. It is different from FAILED in that there is no + // unexpected error happened and it is regarded as a normal state. + enum State { + UNKNOWN = 0; + NEW = 1; + RUNNING = 2; + COMPLETE = 3; + FAILED = 4; + CACHED = 5; + CANCELED = 6; + } + // The last known state of an execution in the system. + optional State last_known_state = 3; + // Properties of the Execution. + // Properties must be specified in the ExecutionType. + map properties = 4; + // User provided custom properties which are not defined by its type. + map custom_properties = 5; + // Output only. Create time of the execution in millisecond since epoch. + optional int64 create_time_since_epoch = 8; + // Output only. Last update time of the execution in millisecond since epoch. + optional int64 last_update_time_since_epoch = 9; + + // Output only. + optional google.protobuf.Any system_metadata = 11; +} + +message ExecutionType { + // The id of the type. 1-1 relationship between type names and IDs. + optional int64 id = 1; + // The name of the type. It must be unique among ExecutionTypes within a + // database instance. + optional string name = 2; + // An optional version of the type. An empty string is treated as unset. + optional string version = 6; + // An optional description about the type. + optional string description = 7; + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all execution types within a database + // instance. + optional string external_id = 9; + // The schema of the type. + // Properties are always optional in the execution. + map properties = 3; + // The ArtifactStructType of the input. + // For example: { + // "dict":{ + // "properties":{ + // "schema":{ + // "union_type":{ + // "none":{}, + // "simple":{...schema type...} + // }, + // }, + // "data":{ + // "simple":{...data_type...} + // } + // } + // } + // } + // That would be an optional schema field with a required data field. + optional ArtifactStructType input_type = 4; + // The ArtifactStructType of the output. + // For example {"simple":{...stats gen output type...}} + optional ArtifactStructType output_type = 5; + + // An enum of system-defined execution types. + enum SystemDefinedBaseType { + UNSET = 0 [(system_type_extension).type_name = 'unset_execution_type']; + TRAIN = 1 [(system_type_extension).type_name = 'mlmd.Train']; + TRANSFORM = 2 [(system_type_extension).type_name = 'mlmd.Transform']; + PROCESS = 3 [(system_type_extension).type_name = 'mlmd.Process']; + EVALUATE = 4 [(system_type_extension).type_name = 'mlmd.Evaluate']; + DEPLOY = 5 [(system_type_extension).type_name = 'mlmd.Deploy']; + } + + // An optional system defined base_type expressing the intent of the current + // type. This field is useful for the tool builders to utilize the stored MLMD + // information, e.g., `MyTrainer` ExecutionType could set base_type = TRAIN. + optional SystemDefinedBaseType base_type = 8; +} + +message ContextType { + // The id of the type. 1-1 relationship between type names and IDs. + optional int64 id = 1; + // The name of the type, e.g., Pipeline, Task, Session, User, etc. It must be + // unique among ContextTypes within a database instance. + optional string name = 2; + // An optional version of the type. An empty string is treated as unset. + optional string version = 4; + // An optional description about the type. + optional string description = 5; + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all context types within a database + // instance. + optional string external_id = 7; + // The schema of the type, e.g., name: string, owner: string + // Properties are always optional in the context. + // Properties of an context type can be expanded but not contracted (i.e., + // you can add columns but not remove them). + map properties = 3; + + // An enum of system-defined context types. + enum SystemDefinedBaseType { + UNSET = 0 [(system_type_extension).type_name = 'unset_context_type']; + } + + // An optional system defined base_type expressing the intent of the current + // context type. + // *NOTE: currently there are no system Context types defined, and the field + // is not used for ContextType. + optional SystemDefinedBaseType base_type = 6; +} + +message Context { + // Output Only. The unique server generated id of the context. + optional int64 id = 1; + // The client provided name of the context. It must be unique within a + // database instance. + optional string name = 3; + // The id of a ContextType. This needs to be specified when a context is + // created, and it cannot be changed. + optional int64 type_id = 2; + // Output only. The name of a ContextType. + optional string type = 6; + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all contexts within a virtual database. + optional string external_id = 9; + // Values of the properties, which must be specified in the ContextType. + map properties = 4; + // User provided custom properties which are not defined by its type. + map custom_properties = 5; + // Output only. Create time of the context in millisecond since epoch. + optional int64 create_time_since_epoch = 7; + // Output only. Last update time of the context in millisecond since epoch. + optional int64 last_update_time_since_epoch = 8; + + // Output only system metadata. + optional google.protobuf.Any system_metadata = 10; +} + +// the Attribution edges between Context and Artifact instances. +message Attribution { + optional int64 artifact_id = 1; + optional int64 context_id = 2; +} + +// the Association edges between Context and Execution instances. +message Association { + optional int64 execution_id = 1; + optional int64 context_id = 2; +} + +// the Parental Context edges between Context and Context instances. +message ParentContext { + optional int64 child_id = 1; + optional int64 parent_id = 2; +} + +// A self-contained provenance (sub)graph representation consists of MLMD nodes +// and their relationships. It is used to represent the query results from the +// persistent backend (e.g., lineage about a node, reachability of two nodes). +message LineageGraph { + // extracted types + repeated ArtifactType artifact_types = 1; + repeated ExecutionType execution_types = 2; + repeated ContextType context_types = 3; + // extracted nodes + repeated Artifact artifacts = 4; + repeated Execution executions = 5; + repeated Context contexts = 6; + // extracted edges + repeated Event events = 7; + repeated Attribution attributions = 8; + repeated Association associations = 9; +} + +// The list of ArtifactStruct is EXPERIMENTAL and not in use yet. +// The type of an ArtifactStruct. +// An artifact struct type represents an infinite set of artifact structs. +// It can specify the input or output type of an ExecutionType. +// See the more specific types referenced in the message for more details. +message ArtifactStructType { + oneof kind { + ArtifactType simple = 1; // Matches exactly this type. + UnionArtifactStructType union_type = 2; + IntersectionArtifactStructType intersection = 3; + ListArtifactStructType list = 4; + NoneArtifactStructType none = 5; + AnyArtifactStructType any = 6; + TupleArtifactStructType tuple = 7; + DictArtifactStructType dict = 8; + } +} + +// Represents a union of types. +message UnionArtifactStructType { + // An artifact struct matches this type if it matches any of the candidates. + // If candidates is empty, this is a bottom type (matches no artifacts). + repeated ArtifactStructType candidates = 1; +} + +// A member of this type must satisfy all constraints. +// This primarily useful not as an end-user type, but something calculated +// as an intermediate type in the system. +// +// For example, suppose you have a method: +// def infer_my_input_type(a): # try to infer the input type of this method. +// use_in_method_x(a) # with input type x_input +// use_in_method_y(a) # with input type y_input +// +// Given this information, you know that infer_my_input_type has +// type {"intersection":{"constraints":[x_input, y_input]}}. +// +// IntersectionArtifactStructType intersection_type = {"constraints":[ +// {"dict":{"properties":{"schema":{"any":{}}}, +// "extra_properties":{"any":{}}}}, +// {"dict":{"properties":{"data":{"any":{}}}, +// "extra_properties":{"any":{}}}}]} +// Since the first constraint requires the dictionary to have a schema +// property, and the second constraint requires it to have a data property, this +// is equivalent to: +// ArtifactStructType other_type = +// {"dict":{"properties":{"schema":{"any":{}},"data":{"any":{}}}}, +// "extra_properties":{"any":{}}} +// +message IntersectionArtifactStructType { + repeated ArtifactStructType constraints = 1; +} + +// Represents an ArtifactStruct list type with homogeneous elements. +message ListArtifactStructType { + // Every entry in the list must be of this type. + // Note: if this type is Any, then the list can have arbitrary elements. + optional ArtifactStructType element = 1; +} + +// The only member of this type is a None artifact. +// Note: ArtifactStruct{} is a None artifact. +// This can represent an execution that has no outputs (or inputs), +// or can be part of a UnionArtifactStructType to represent an optional +// input. +// For example, StatsGen has an "optional" schema input. +// A practical example of this is: +// stats_gen_type = { +// "dict":{ +// "properties":{ +// "schema":{ +// "union_type":{ +// "none":{}, +// "simple":{...schema type...} +// }, +// }, +// "data":{ +// "simple":{...data_type...} +// } +// } +// } +// }; +message NoneArtifactStructType {} + +// Every ArtifactStruct is a member of this type. +message AnyArtifactStructType {} + +// An ordered list of heterogeneous artifact structs. +// The length of the list is fixed. +// Each position in the list can have a different type. +message TupleArtifactStructType { + repeated ArtifactStructType elements = 1; +} + +// A artifact struct type that represents a record or struct-like dictionary. +// ArtifactStruct would be map (i.e. ArtifactStructMap) +message DictArtifactStructType { + // Underlying properties for the type. + map properties = 1; + + // If true, then if properties["foo"] can be None, then that key is not + // required. + optional bool none_type_not_required = 2; + + // Extra keys are allowed that are not specified in properties. These + // keys must have the type specified below. + // If this is not specified, then extra properties are not allowed. + optional ArtifactStructType extra_properties_type = 3; +} + +// Configuration for a "fake" database. +// This database is an in-memory SQLite database that lives only as +// long as the associated object lives. +message FakeDatabaseConfig {} + +message MySQLDatabaseConfig { + // The hostname or IP address of the MYSQL server: + // * If unspecified, a connection to the local host is assumed. + // The client connects using a Unix socket specified by `socket`. + // * Otherwise, TCP/IP is used. + // Currently a replicated MYSQL backend is not supported. + optional string host = 1; + // The TCP Port number that the MYSQL server accepts connections on. + // If unspecified, the default MYSQL port (3306) is used. + optional int64 port = 2; + // The database to connect to. Must be specified. + // After connecting to the MYSQL server, this database is created if not + // already present unless skip_db_creation is set. + // All queries after Connect() are assumed to be for this database. + optional string database = 3; + // The MYSQL login id. If empty, the current user is assumed. + optional string user = 4; + // The password to use for `user`. If empty, only MYSQL user ids that don't + // have a password set are allowed to connect. + optional string password = 5; + // The Unix socket to use to connect to the server. If unspecified, a + // `host` must be provided. + optional string socket = 6; + + // The options to establish encrypted connections to MySQL using SSL. + message SSLOptions { + // The path name of the client private key file. + optional string key = 1; + // The path name of the client public key certificate file. + optional string cert = 2; + // The path name of the CA certificate file. + optional string ca = 3; + // The path name of the directory that contains trusted SSL CA certificates. + optional string capath = 4; + // The list of permissible ciphers for SSL encryption. + optional string cipher = 5; + // If set, enable verification of the server certificate against the host + // name used when connecting to the server. + optional bool verify_server_cert = 6; + } + // If the field is set, the ssl options are set in mysql_options before + // establishing a connection. It is ignored if the mysql server does not + // enable SSL. + optional SSLOptions ssl_options = 7; + + // A config to skip the database creation if not exist when connecting the + // db instance. It is useful when the db creation is handled by an admin + // process, while the lib user should not issue db creation clauses. + optional bool skip_db_creation = 8; +} + +// A config contains the parameters when using with SqliteMetadatSource. +message SqliteMetadataSourceConfig { + // A uri specifying Sqlite3 database filename, for example: + // + // file:some_sqlite3_file_in_local_dir.db + // file:///home/username/some_sqlite3_file.db + // + // see https://www.sqlite.org/c3ref/open.html for model details + // + // If not given, a in-memory sqlite3 database is used, and destroyed when + // disconnecting the metadata source. + optional string filename_uri = 1; + + // Connection parameters for SQLite3 based metadata source. + enum ConnectionMode { + UNKNOWN = 0; + // Connect a metadata source in read-only mode. Connection fail if the + // sqlite3 database at the `filename` does not exist. Any queries modifying + // the database fail. + READONLY = 1; + // Connect a metadata source in read/write mode. Connection fail if the + // sqlite3 database at the `filename` does not exist. + READWRITE = 2; + // Similar to READWRITE. In addition, it creates the database if it does not + // exist. + READWRITE_OPENCREATE = 3; + } + + // A flag specifying the connection mode. If not given, default connection + // mode is set to READWRITE_OPENCREATE. + optional ConnectionMode connection_mode = 2; +} + +// A config contains the parameters when using with PostgreSQLMetadatSource. +// Next index: 10 +message PostgreSQLDatabaseConfig { + // Name of host to connect to. If the host name starts with /, it is taken as + // a Unix-domain socket in the abstract namespace. + optional string host = 1; + + // Numeric IP address of host to connect to. If this field is provided, `host` + // field is ignored. + optional string hostaddr = 2; + + // Port number to connect to at the server host, or socket file name extension + // for Unix-domain connections. + optional string port = 3; + + // PostgreSQL user name to connect as. Defaults to be the same as the + // operating system name of the user running the application. + optional string user = 4; + + // Password to be used if the server demands password authentication. + optional string password = 5; + + // Specifies the name of the file used to store passwords. + optional string passfile = 6; + + // The database name. Defaults to be the same as the user name. + optional string dbname = 7; + + // A config to skip the database creation if not exist when connecting the + // db instance. It is useful when the db creation is handled by an admin + // process, while the lib user should not issue db creation clauses. + optional bool skip_db_creation = 8; + + message SSLOptions { + // disable, allow, verify-ca, verify-full, etc. Reference: + // https://www.postgresql.org/docs/current/libpq-connect.html + optional string sslmode = 1; + + // This parameter specifies the file name of the client SSL certificate, + // replacing the default ~/.postgresql/postgresql.crt. This parameter is + // ignored if an SSL connection is not made. + optional string sslcert = 2; + + // This parameter specifies the location for the secret key used for the + // client certificate. It can either specify a file name that will be used + // instead of the default ~/.postgresql/postgresql.key, this parameter is + // ignored if an SSL connection is not made. + optional string sslkey = 3; + + // This parameter specifies the password for the secret key specified in + // sslkey, allowing client certificate private keys to be stored in + // encrypted form on disk even when interactive passphrase input is not + // practical. + optional string sslpassword = 4; + + // This parameter specifies the name of a file containing SSL certificate + // authority (CA) certificate(s). If the file exists, the server's + // certificate will be verified to be signed by one of these authorities. + // The default is ~/.postgresql/root.crt. + optional string sslrootcert = 5; + } + + optional SSLOptions ssloption = 9; +} + + +message MigrationOptions { + // If not set, by default the upgrade migration is disabled. MLMD only + // compares db_v with the lib_v, and raise error if the two do not align. + // If the field is set to true, MLMD performs upgrade migration. It upgrades + // the database schema version (db_v) to align with the library schema + // version (lib_v) when connecting to the database. + // Schema migration should not be run concurrently with multiple clients to + // prevent data races. + optional bool enable_upgrade_migration = 3; + + // Downgrade the given database to the specified schema version. + // For v0.13.2 release, the schema_version is 0. + // For 0.14.0 and 0.15.0 release, the schema_version is 4. + // More details are described in g3doc/get_start.md#upgrade-mlmd-library + // Set this field only when a database is accidentally upgraded by a newer + // version library. Each library version only knows how to downgrade to + // previous schema versions. As downgrade migrations inevitably introduce + // data loss, please consider taking a backup of the database before + // downgrading schema. + // After downgrade migration, the database connection is canceled. The user + // needs to downgrade the library to use the database. + optional int64 downgrade_to_schema_version = 2 [default = -1]; + + reserved 1; +} + +message RetryOptions { + // The max number of retries when transaction returns Aborted error. + optional int64 max_num_retries = 1; +} + +message ConnectionConfig { + // Configuration for a new connection. + oneof config { + FakeDatabaseConfig fake_database = 1; + MySQLDatabaseConfig mysql = 2; + SqliteMetadataSourceConfig sqlite = 3; + + // PostgreSQL database connection config. + PostgreSQLDatabaseConfig postgresql = 5; + + } + + // Options for overwriting the default retry setting when MLMD transactions + // returning Aborted error. + // The setting is currently available for python client library only. + // TODO(b/154862807) set the setting in transaction executor. + optional RetryOptions retry_options = 4; +} + +// A list of supported GRPC arguments defined in: +// https://grpc.github.io/grpc/core/group__grpc__arg__keys.html +message GrpcChannelArguments { + // Maximum message length in bytes per response that the channel can receive. + optional int64 max_receive_message_length = 1; + // Maximum misbehaving pings the server can bear before sending goaway and + // closing the transport? (0 indicates infinite number of misbehaving pings) + optional int64 http2_max_ping_strikes = 2; +} + +// Configuration for the gRPC metadata store client. +message MetadataStoreClientConfig { + // The hostname or IP address of the gRPC server. Must be specified. + optional string host = 1; + // The TCP Port number that the gRPC server accepts connections on. + // Must be specified. + optional int64 port = 2; + + message SSLConfig { + // The PEM-encoded private key as a byte string, or Empty if no private key + // should be used. + optional string client_key = 1; + // The PEM-encoded certificate chain as a byte string to use or or Empty if + // no certificate chain should be used. + optional string server_cert = 2; + // The PEM-encoded root certificates as a byte string, or Empty to retrieve + // them from a default location chosen by gRPC runtime. + optional string custom_ca = 3; + } + + // Configuration for a secure gRPC channel. + // If not given, insecure connection is used. + optional SSLConfig ssl_config = 3; + + // GRPC channel creation arguments. + optional GrpcChannelArguments channel_arguments = 4; + + // Time duration that a client is willing to wait for a reply from the server. + // If unset, the timeout is considered infinite. When the field is specified, + // Grpc APIs would return DeadlineExceededError when server does not respond + // within `client_timeout_sec`. Floating point valued, in seconds. + optional double client_timeout_sec = 5; + +} + +// Configuration for the gRPC metadata store server. +message MetadataStoreServerConfig { + // Configuration to connect the metadata source backend. + optional ConnectionConfig connection_config = 1; + + // Configuration for upgrade and downgrade migrations the metadata source. + optional MigrationOptions migration_options = 3; + + message SSLConfig { + // Private server key for SSL + optional string server_key = 1; + // Public server certificate + optional string server_cert = 2; + // Custom certificate authority + optional string custom_ca = 3; + // Valid client certificate required? + optional bool client_verify = 4; + } + + // Configuration for a secure gRPC channel. + // If not given, insecure connection is used. + optional SSLConfig ssl_config = 2; +} + +// ListOperationOptions represents the set of options and predicates to be +// used for List operations on Artifacts, Executions and Contexts. +message ListOperationOptions { + // Max number of resources to return in the result. A value of zero or less + // results in a InvalidArgumentError. + // The API implementation also enforces an upper-bound of 100, and picks the + // minimum between this value and the one specified here. + optional int32 max_result_size = 1 [default = 20]; + + message OrderByField { + // Supported fields for Ordering. + enum Field { + FIELD_UNSPECIFIED = 0; + CREATE_TIME = 1; + LAST_UPDATE_TIME = 2; + ID = 3; + } + + // Field to order. + optional Field field = 1 [default = ID]; + + // Direction of ordering. + optional bool is_asc = 2 [default = true]; + } + + // Ordering field. + optional OrderByField order_by_field = 2; + + // Identifies the next page of results. + optional string next_page_token = 3; + + // A boolean expression in SQL syntax that is used to specify the conditions + // on node attributes and directly connected assets. + // + // In the current implementation, filtering Artifact/Execution/Context with + // the following attributes and neighborhood is supported: + // + // Attributes: + // id:int64, type_id:int64, type:string, + // uri:string, name: string, external_id: string, + // create_time_since_epoch:int64, last_update_time_since_epoch:int64 + // state:ENUM (Artifact only) last_known_state:ENUM (Execution only) + // + // Neighborhood + // - Properties and Custom Properties (for all node types): + // syntax: properties.$name ($name is the property name) + // custom_properties.$name ($name is the custom property name) + // attributes: the following attributes can be used + // int_value: int64, double_value: double, string_value: string + // bool_value: bool + // + // - Context (for Artifact and Execution): + // syntax: contexts_$alias ($alias can be [0-9A-Za-z_]) + // attributes: the following attributes can be used + // id:int64, name:string, type:string, create_time_since_epoch:int64, + // last_update_time_since_epoch: int64 + // + // - Parent and Child Contexts (for Contexts): + // syntax: parent_contexts_$alias( $alias can be [0-9A-Za-z_] + // child_contexts_$alias( $alias can be [0-9A-Za-z_] + // attributes: the following attributes can be used + // id:int64, name: string, type:string + // + // - Event (for Artifact and Execution) + // syntax: events_$alias ($alias can be [0-9A-Za-z_]) + // attributes: the following attributes can be used + // artifact_id: int64(Execution only), execution_id: int64(Artifact only), + // type: ENUM, milliseconds_since_epoch: int64 + // + // Examples: + // a) to filter nodes attributes: + // - id != 1 + // - id IN (1, 3) + // - type_id = 5 + // - type = 'my_type_name' + // - name = 'foo' + // - type = 'bar' AND name LIKE 'foo%' + // - external_id = 'my_external_id' + // - NOT(create_time_since_epoch < 1 OR last_update_time_since_epoch < 1) + // + // b) to filter artifacts' uri + // - uri = 'exact_path_string' + // - uri LIKE 'path_like_this%' + // - uri IS NOT NULL + // + // c) to filter artifact's state or execution's last_known_state + // - state = LIVE + // - state IS NULL + // - state IN (PENDING, LIVE) + // - last_known_state = RUNNING + // - last_known_state != RUNNING + // - last_known_state NOT IN (FAILED, CANCELED) + // + // d) to filter nodes having a specific context, artifact, or execution + // - contexts_a.id = 5 + // - contexts_a.type = 'RunContext' + // - contexts_a.name = 'my_run' + // - contexts_a.create_time_since_epoch = 1626761453 + // - contexts_a.last_update_time_since_epoch = 1626761453 + // To filter nodes with conditions on multiple contexts: + // - contexts_a.name = 'my_run' AND contexts_b.name = 'my_pipeline' + // To filter context with artifacts: + // - artifacts_a.id = 5 + // - artifacts_a.type = 'Dataset' + // - artifacts_a.name = 'my_dataset' + // - artifacts_a.uri = 'exact_path_string' + // - artifacts_a.state = LIVE + // - artifacts_a.state IN (PENDING, LIVE) + // - artifacts_a.external_id = "my_external_id" + // - artifacts_a.create_time_since_epoch = 1626761453 + // - artifacts_a.last_update_time_since_epoch = 1626761453 + // To filter contexts with conditions on multiple artifacts: + // - artifacts_a.name = 'my_run' AND artifacts_b.name = 'my_pipeline' + // To filter context with executions: + // - executions_a.id = 5 + // - executions_a.type = 'Dataset' + // - executions_a.name = 'my_dataset' + // - executions_a.last_known_state = RUNNING + //. - executions_a.last_known_state IN (NEW, RUNNING) + // - executions_a.external_id = "my_external_id" + // - executions_a.create_time_since_epoch = 1626761453 + // - executions_a.last_update_time_since_epoch = 1626761453 + // To filter contexts with conditions on multiple executions: + // - executions_a.name = 'my_run' AND executions_b.name = 'my_pipeline' + // + // e) to filter nodes condition on their properties + // - properties.accuracy.double_value > 0.95 + // - custom_properties.my_param.string_value = "foo" + // If the name of the property or custom property includes characters + // other than [0-9A-Za-z_], then the name need to be backquoted, + // e.g., + // - properties.`my property`.int_value > 0 + // - custom_properties.`my:custom.property`.bool_value = true + // + // f) complex query to filter both node attributes and neighborhood + // - type = 'DataSet' AND + // (contexts_a.type = 'RunContext' AND contexts_a.name = 'my_run') AND + // (properties.span = 1 OR custom_properties.span = 1) + // + // g) to filter parent/child context + // - parent_contexts_a.id = 5 + // - child_contexts_a.type = 'RunContext' + // - parent_contexts_a.name = 'parent_context_1' + // + // h) to filter Artifacts on Events + // - events_0.execution_id = 1 + // - events_0.type = INPUT + // - events_0.milliseconds_since_epoch = 1 + // to filter Executions on Events + // - events_0.artifact_id = 1 + // - events_0.type IN (INPUT, INTERNAL_INPUT) + // - events_0.milliseconds_since_epoch = 1 + // TODO(b/145945460) Support filtering on event step fields. + optional string filter_query = 4; +} + +// Encapsulates information to identify the next page of resources in +// ListOperation. +message ListOperationNextPageToken { + // Id offset within the resultset to start next page. + // Id offset is returned as Id is the unique field used to break ties for + // fields that might have duplicate entries, e.g. there could be two + // resources with same create_time. In such cases to break the tie in + // ordering, id offset is used. + // This field is currently only set whe order_by field is CREATE_TIME. + optional int64 id_offset = 1; + + // Offset value of the order by field. If ID is used this value is same as + // id_offset. + optional int64 field_offset = 2; + + // Options set in the first call to ListOperation. This ensures that if + // next_page_token is set by the caller then ListPipelineJobs API will always + // use options set in the first call. + optional ListOperationOptions set_options = 3; + + // List of ids that have the same order_by field values. This is used to + // ensure List Operation does not return duplicate entries for nodes that have + // the same order_by field value. + // This field is currently only set whe order_by field is LAST_UPDATE_TIME. + repeated int64 listed_ids = 4; + +} + +// Options for transactions. +// Note: This is under development. Clients should not use it. +message TransactionOptions { + extensions 1000 to max; + + // Transaction tag for debug use only. + optional string tag = 1; +} + + +// TODO(b/283852485): Deprecate GetLineageGraph API after migration to +// GetLineageSubgraph API. +// The query options for `get_lineage_graph` operation. +// `query_nodes` is a list of nodes of interest. +// Currently only artifacts are supported as `query_nodes`. +// `stop_conditions` defines the filtering rules when querying a lineage graph. +// `max_node_size` defines the total number of artifacts and executions returned +// in the subgraph. +message LineageGraphQueryOptions { + // A query to specify the nodes of interest. + // `ListOperationOptions.max_result_size` sets the maximum number of nodes to + // begin with the graph search. + // TODO(b/178491112) Support query_nodes for Executions. + oneof query_nodes { + ListOperationOptions artifacts_options = 1; + } + + // Filtering conditions for retrieving the lineage graph. + message BoundaryConstraint { + // The maximum number of hops from the `query_nodes` to traverse. + // A hop is defined as a jump to the next node following the path of + // node -> event -> next_node. + // For example, in the lineage graph a_1 -> e_1 -> a_2: + // a_2 is 2 hops away from a_1, and e_1 is 1 hop away from a_1. + // `max_num_hops` should be non-negative. + // When its value is set to 0, only the `query_nodes` are returned. + optional int64 max_num_hops = 1; + + // Filtering conditions for retrieving the lineage graph. + // Please refer to `ListOperationOptions.filter_query` for the syntax. + // + // If set, the `boundary_artifacts` defines which artifacts to keep in the + // returned lineage graph during the graph search. + // Artifacts that do not satisfy the `boundary_artifacts` are filtered out, + // and the subgraphs starting at them will be pruned. + // If not set, no artifacts will be filtered out. + // Taking the following lineage graph as example: + // (`a` represents an Artifact, `e` represents an Execution, each arrow + // represents a hop.) + // a_0 a_1 a_3 + // | \ / \ + // \/ \/ \/ \/ + // e_0 e_1 e_3 + // / \ + // \/ \/ + // a_2 a_4 a_5 + // \ / + // \/ \/ + // e_2 + // To query all the upstream and downstream nodes 3 hops away from a_4, + // while excluding the upstream subgraph starting at a_3, then + // `stop_conditions` can be set as: + // { + // max_num_hops: 3 + // boundary_artifacts: 'id != 3' + // } + // With the `stop_conditions`, {a_3, e_1, a_1, a_0, e_0} will be filtered + // out. + // The returned lineage graph looks like: + // e_3 + // / \ + // \/ \/ + // a_2 a_4 a_5 + // \ / + // \/ \/ + // e_2 + optional string boundary_artifacts = 2; + // If set, the `boundary_executions` defines which executions to keep in the + // returned lineage graph during the graph search. + // Executions that do not satisfy the `boundary_executions` are filtered out + // and the subgraphs starting at them will be pruned. + // If not set, no executions will be filtered out. + // In the example above, to query for all the upstream and downstream nodes + // 3 hops away from a_4, while excluding the upstream subgraph and the + // downstream subgraph starting at e_3, then `stop_conditions` can be set as + // { + // max_num_hops: 3 + // boundary_executions: 'id != 3' + // } + // With the `stop_conditions`, {e_3, a_5, a_3, e_1, a_1, a_0, e_0} will be + // filtered out. + // The returned lineage graph looks like: + // a_2 a_4 + // \ / + // \/ \/ + // e_2 + // However, for the following graph: + // a_0 a_1 a_3 + // | \ / \ + // \/ \/ \/ \/ + // e_0 e_1 e_3 + // \ / \ + // \/ \/ \/ + // a_2 a_4 a_5 + // \ / + // \/ \/ + // e_2 + // With the same `stop_conditions`, only {e_3, a_5, a_0, e_0} will be + // filtered out. + // The returned lineage graph looks like: + // a_1 a_3 + // \ / + // \/ \/ + // e_1 + // \ + // \/ + // a_2 a_4 + // \ / + // \/ \/ + // e_2 + optional string boundary_executions = 3; + } + + // A constraint option to define the filtering rules when querying a lineage + // graph. + optional BoundaryConstraint stop_conditions = 2; + + // Maximum total number of artifacts and executions in the whole returned + // lineage graph. + // If set to 0 or below, all related nodes will be returned without any + // number limitation. + // The number counts toward Artifacts and Executions. Nothing else considered. + // + // NOTE: There is no pagination supported. + optional int64 max_node_size = 3 [default = 20]; +} + +// The query options for lineage graph tracing from a list of interested nodes. +message LineageSubgraphQueryOptions { + // `starting_nodes` is a list of nodes of interest to start graph tracing. + // NOTE: The maximum number of starting nodes is 100 at most. + message StartingNodes { + // `filter_query` is a boolean expression in SQL syntax that is used to + // specify the conditions on starting nodes. + // Please refer to ListOperationOptions.filter_query for more details. + optional string filter_query = 1; + } + + oneof starting_nodes { + StartingNodes starting_artifacts = 1; + StartingNodes starting_executions = 2; + } + + // The maximum number of hops from the `starting_nodes` to traverse. + // A hop is defined as a jump to the next node following the path of + // node -> event -> next_node. + // For example, in the lineage graph a_1 -> e_1 -> a_2: + // a_2 is 2 hops away from a_1, and e_1 is 1 hop away from a_1. + // `max_num_hops` should be non-negative. + // When its value is set to 0, only the `starting_nodes` are returned. + optional int64 max_num_hops = 3; + + enum Direction { + // Direction is by defult DIRECTION_UNSPECIFIED, which is equivalent to + // BIDIRECTIONAL. + DIRECTION_UNSPECIFIED = 0; + // Indicates tracing the lineage graph by hops in upstream direction. + UPSTREAM = 1; + // Indicates tracing the lineage graph by hops in downstream direction. + DOWNSTREAM = 2; + // Indicates tracing the lineage graph in both directions. + BIDIRECTIONAL = 3; + } + // The direction of lineage graph tracing, which means the direction of all + // hops in the tracing. + // An UPSTREAM hop means an expansion following the path of + // execution -> output_event -> artifact or + // artifact -> input_event -> execution + // A DOWNSTREAM hop means an expansion following the path of + // execution -> input_event -> artifact or + // artifact -> output_event -> execution + // Please refer to `Direction` for more details. + optional Direction direction = 4; +} diff --git a/ml_metadata/proto/metadata_store_service.proto b/ml_metadata/proto/metadata_store_service.proto new file mode 100644 index 00000000..d7238cf0 --- /dev/null +++ b/ml_metadata/proto/metadata_store_service.proto @@ -0,0 +1,1525 @@ +/* Copyright 2019 Google LLC + +Licensed 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 + + https://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. +==============================================================================*/ + +syntax = "proto2"; +option go_package = "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto"; + +package ml_metadata; + +import "google/protobuf/field_mask.proto"; +import "ml_metadata/proto/metadata_store.proto"; + +// An artifact and type pair. Part of an artifact struct. +message ArtifactAndType { + optional Artifact artifact = 1; + optional ArtifactType type = 2; +} + +// A dictionary of artifact structs. Can represent a dictionary. +message ArtifactStructMap { + // An artifact struct that is a dictionary. + // Can be represented as a JSON dictionary of artifact structs. + map properties = 1; +} + +// An artifact struct that is a list. +message ArtifactStructList { + // Can be represented as a JSON list of artifact structs. + repeated ArtifactStruct elements = 1; +} + +// An artifact struct represents the input or output of an Execution. +// See the more specific types referenced in the message for more details. +message ArtifactStruct { + // Note: an artifact struct may be empty to indicate "None" or null. + oneof value { + ArtifactAndType artifact = 1; + ArtifactStructMap map = 2; + ArtifactStructList list = 3; + } +} + +message PutArtifactsRequest { + repeated Artifact artifacts = 1; + + message Options { + // When there are multiple writers to update an existing node to + // different states, there may be a race and the end result of the + // concurrent update is nondeterministic. If the field is set, then an + // optimistic concurrency control (OCC) scheme is used during update: + // it compares the `artifact`.`last_update_time_since_epoch` in the request + // with the stored `last_update_time_since_epoch` having the same + // `artifact`.`id`. If they are different, the request fails, and the user + // can read the stored node and retry node update. + // When the option is set, the timestamp after update is guaranteed to be + // increased and different from the input artifact. + // When set the option, the caller should set it for all concurrent writers. + optional bool abort_if_latest_updated_time_changed = 1; + } + + // Additional options to change the behavior of the method. + optional Options options = 2; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; + + // FieldMask for artifacts in the PUT update + // If `artifact.id` is not specified, it means a new artifact will be created + // and `update_mask` will not be applied to the creation. + // If `update_mask` is empty, update the artifacts as a whole. + // If `update_mask` is not empty, only update fields or properties specified + // in `update_mask`. + // Example request protos: + // 1. Examples that update `properties` / `custom_properties`: + // 1.1 Add a <'key', 'val'> pair into `custom_properties`: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // string_value: "val" + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 1.2 Set `custom_properties['key'].bool_value` to true: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // bool_value: true + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 1.3 Delete the complete <'key', 'val'> pair from `custom_properties`: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // custom_properties {} + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 2. Examples that update fields such as `uri`, `external_id`, etc: + // 2.1 Update `external_id` field: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // external_id: "new_value" + // } + // update_mask { + // paths: "external_id" + // } + // } + // 2.2 Set `uri` field: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // uri: "set_value" + // } + // update_mask { + // paths: "uri" + // } + // } + // If `paths: "properties"` or `paths: "custom_properties"` are added to + // `update_mask`, the key-level updates will be ignored and we only perform + // field-level updates on the all `properties`/`custom_properties`. + // For example: + // If the mask is: {"properties", "properties.key1"}, the field path + // "properties.key1" will be ignored and all `properties` will be updated. + // (Do not suggest) + // If the mask is {"properties", "external_id"}, all + // `properties` and field `external_id` will be updated. (Do not suggest) + optional google.protobuf.FieldMask update_mask = 4; +} + +message PutArtifactsResponse { + // A list of artifact ids index-aligned with PutArtifactsRequest. + repeated int64 artifact_ids = 1; +} + +message PutArtifactTypeRequest { + // The field is required in any request. Stored types in MLMD can be updated + // by introducing new properties and remain backward compatible. If a type + // with the same name exists in the database, it updates the existing type, + // otherwise it creates a new type. + optional ArtifactType artifact_type = 1; + + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + optional bool can_add_fields = 2; + + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + optional bool can_omit_fields = 5; + + // Deprecated fields. + optional bool can_delete_fields = 3 [deprecated = true]; + optional bool all_fields_match = 4 [default = true, deprecated = true]; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 6; +} + +message PutArtifactTypeResponse { + // The type ID of the artifact type. + optional int64 type_id = 1; +} + +message PutExecutionsRequest { + repeated Execution executions = 1; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; + + // FieldMask for executions in the PUT update + // If `execution.id` is not specified, it means a new execution will be + // created and `update_mask` will not be applied to the creation. + // If `update_mask` is empty, update the executions as a whole. + // If `update_mask` is not empty, only update fields or properties specified + // in `update_mask`. + // Example request protos: + // 1. Add a <'key', 'val'> pair into `custom_properties`: + // { + // executions { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // string_value: "val" + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 2. Set `last_known_state` field: + // { + // executions { + // id: 1234 + // type_id: 5678 + // last_known_state: CACHED + // } + // update_mask { + // paths: "last_known_state" + // } + // } + // Please refer to `PutArtifactsRequest` for more details. + optional google.protobuf.FieldMask update_mask = 3; +} + +message PutExecutionsResponse { + // A list of execution ids index-aligned with PutExecutionsRequest. + repeated int64 execution_ids = 1; +} + +message PutExecutionTypeRequest { + // The field is required in any request. Stored types in MLMD can be updated + // by introducing new properties and remain backward compatible. If a type + // with the same name exists in the database, it updates the existing type, + // otherwise it creates a new type. + optional ExecutionType execution_type = 1; + + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + optional bool can_add_fields = 2; + + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + optional bool can_omit_fields = 5; + + // Deprecated fields. + optional bool can_delete_fields = 3 [deprecated = true]; + optional bool all_fields_match = 4 [default = true, deprecated = true]; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 6; +} + +message PutExecutionTypeResponse { + // The type ID of the execution type. + optional int64 type_id = 1; +} + +message PutEventsRequest { + repeated Event events = 1; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message PutEventsResponse {} + +message PutExecutionRequest { + // A pair of an artifact and an event used or generated by an execution, e.g., + // during the execution run, it uses none or many artifacts as input, and + // generate none or many artifacts as output. + message ArtifactAndEvent { + // The pair may have an artifact. If present and no artifact.id is given, + // then it inserts the artifact, otherwise it updates the artifact. + optional Artifact artifact = 1; + // The pair may have an event. Providing event.artifact_id or + // event.execution_id is optional. If the ids are given, it must align with + // the `artifact`.id / `execution`.id respectively. If artifact is not + // given and event.artifact_id is set, it must exist in the backend. + optional Event event = 2; + } + + message Options { + // When there's a race to publish executions with a new context with the + // same context.name, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. If set to true, + // the API will reuse the stored context in the transaction and perform + // an update. + optional bool reuse_context_if_already_exist = 1; + + // When there's a race to publish executions with a new artifact with the + // same artifact.external_id, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. + // If set to true and an Artifact has non-empty external_id, + // the API will reuse the stored artifact in the transaction and + // perform an update. Otherwise, it will fall back to relying on `id` field + // to decide if it's update (if `id` exists) or insert (if `id` is empty). + optional bool reuse_artifact_if_already_exist_by_external_id = 2; + } + // The execution that produces many artifact and event pairs. + optional Execution execution = 1; + // The list of artifact and event pairs. + repeated ArtifactAndEvent artifact_event_pairs = 2; + // A list of contexts associated with the execution and artifacts. For each + // given context without a context.id, it inserts the context, otherwise it + // updates the stored context with the same id. + // Associations between each pair of contexts and the execution, and + // attributions between each pair of contexts and artifacts are created if + // they do not already exist. + repeated Context contexts = 3; + // Additional options to change the behavior of the method. + optional Options options = 4; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 5; +} + +message PutExecutionResponse { + // An execution id of the `execution` in PutExecutionRequest. + optional int64 execution_id = 1; + // A list of artifact ids index-aligned with `artifact_event_pairs` in the + // PutExecutionRequest. + repeated int64 artifact_ids = 2; + // A list of context ids index-aligned with `contexts` in the + // PutExecutionRequest. + repeated int64 context_ids = 3; +} + +message PutLineageSubgraphRequest { + repeated Execution executions = 1; + repeated Artifact artifacts = 2; + repeated Context contexts = 3; + + message EventEdge { + // Index in the array of executions. + optional int32 execution_index = 1; + // Index in the array of artifacts. + optional int32 artifact_index = 2; + optional Event event = 3; + } + repeated EventEdge event_edges = 4; + + message Options { + // When there's a race to publish executions with a new context with the + // same context.name, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. If set to true, + // the API will reuse the stored context in the transaction and perform + // an update. + optional bool reuse_context_if_already_exist = 1; + + // When there's a race to publish executions with a new artifact with the + // same artifact.external_id, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. + // If set to true and an Artifact has non-empty external_id, + // the API will reuse the stored artifact in the transaction and + // perform an update. Otherwise, it will fall back to relying on `id` field + // to decide if it's update (if `id` exists) or insert (if `id` is empty). + optional bool reuse_artifact_if_already_exist_by_external_id = 2; + } + optional Options options = 5; + + optional TransactionOptions transaction_options = 6; +} + +message PutLineageSubgraphResponse { + // A list of execution ids index-aligned with `executions` in the request + repeated int64 execution_ids = 1 [packed = true]; + // A list of artifact ids index-aligned with `artifacts` in the request + repeated int64 artifact_ids = 2 [packed = true]; + // A list of context ids index-aligned with `contexts` in the request + repeated int64 context_ids = 3 [packed = true]; +} + +message PutTypesRequest { + repeated ArtifactType artifact_types = 1; + repeated ExecutionType execution_types = 2; + repeated ContextType context_types = 3; + + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + optional bool can_add_fields = 4; + + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + optional bool can_omit_fields = 7; + + // Deprecated fields. + optional bool can_delete_fields = 5 [deprecated = true]; + optional bool all_fields_match = 6 [default = true, deprecated = true]; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 8; +} + +message PutTypesResponse { + // The type ids of the artifact type. + repeated int64 artifact_type_ids = 1; + // The type ids of the execution type. + repeated int64 execution_type_ids = 2; + // The type ids of the context type. + repeated int64 context_type_ids = 3; +} + +message PutContextTypeRequest { + // The field is required in any request. Stored types in MLMD can be updated + // by introducing new properties and remain backward compatible. If a type + // with the same name exists in the database, it updates the existing type, + // otherwise it creates a new type. + optional ContextType context_type = 1; + + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + optional bool can_add_fields = 2; + + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + optional bool can_omit_fields = 5; + + // Deprecated fields. + optional bool can_delete_fields = 3 [deprecated = true]; + optional bool all_fields_match = 4 [default = true, deprecated = true]; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 6; +} + +message PutContextTypeResponse { + // The type ID of the context type. + optional int64 type_id = 1; +} + +message PutContextsRequest { + repeated Context contexts = 1; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; + + // FieldMask for contexts in the PUT update + // If `context.id` is not specified, it means a new context will be + // created and `update_mask` will not be applied to the creation. + // If `update_mask` is empty, update the contexts as a whole. + // If `update_mask` is not empty, only update fields or properties specified + // in `update_mask`. + // Example request protos: + // 1. Add a <'key', 'val'> pair into `custom_properties`: + // { + // contexts { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // string_value: "val" + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 2. Set `name` field: + // { + // contexts { + // id: 1234 + // type_id: 5678 + // name: "set_name" + // } + // update_mask { + // paths: "name" + // } + // } + // Please refer to `PutArtifactsRequest` for more details. + optional google.protobuf.FieldMask update_mask = 3; +} + +message PutContextsResponse { + // A list of context ids index-aligned with PutContextsRequest. + repeated int64 context_ids = 1; +} + +message PutAttributionsAndAssociationsRequest { + repeated Attribution attributions = 1; + repeated Association associations = 2; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; +} + +message PutAttributionsAndAssociationsResponse {} + +message PutParentContextsRequest { + repeated ParentContext parent_contexts = 1; + + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message PutParentContextsResponse {} + +message GetArtifactsByTypeRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name with default type_version. + optional string type_version = 2; + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + // If set, the request will + // first fetch all artifacts with specified `type_name` and `type_version`, + // then order by a specifield field + // finally find the correct page and return #Artifacts of the page size. + // Higher-level APIs may only use the functionalies partially. + // Please reference the API documentation for the API behaviors. + optional ListOperationOptions options = 3; + // Options regarding transactions. + optional TransactionOptions transaction_options = 4; +} + +message GetArtifactsByTypeResponse { + repeated Artifact artifacts = 1; + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; +} + +message GetArtifactByTypeAndNameRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name and artifact_name with + // default type_version. + optional string type_version = 3; + optional string artifact_name = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 4; +} + +message GetArtifactByTypeAndNameResponse { + optional Artifact artifact = 1; +} + +message GetArtifactsByIDRequest { + // A list of artifact ids to retrieve. + repeated int64 artifact_ids = 1; + // An option to populate all the ArtifactTypes in the response. + // If true, returns retrieved Artifacts and their artifact types, which can be + // matched by type_ids. + // If false, returns only the retrieved Artifacts. + // Example request proto: + // { + // artifact_ids: 101, + // populate_artifact_types: true, + // } + // The response will contain an artifact with id = 101 and an artifact type + // with id = artifact.type_id(). + optional bool populate_artifact_types = 3 [default = false]; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetArtifactsByIDResponse { + // Artifacts with matching ids. + // This is not index-aligned: if an id is not found, it is not returned. + repeated Artifact artifacts = 1; + // ArtifactTypes populated with matching type_ids owned by `artifacts`. + // This is not index-aligned: if a type_id is not found, it is not returned. + repeated ArtifactType artifact_types = 2; +} + +// Request to retrieve Artifacts using List options. +// If option is not specified then all Artifacts are returned. +message GetArtifactsRequest { + // Specify options. + // Please refer to the documentation of ListOperationOptions for the supported + // functionalities. + optional ListOperationOptions options = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetArtifactsResponse { + // Returned artifacts. + repeated Artifact artifacts = 1; + + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; +} + +message GetArtifactsByURIRequest { + // A list of artifact uris to retrieve. + repeated string uris = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; + + reserved 1; +} + +message GetArtifactsByURIResponse { + repeated Artifact artifacts = 1; +} + +// Request to retrieve Executions using List options. +// If option is not specified then all Executions are returned. +message GetExecutionsRequest { + // Specify options. + // Please refer to the documentation of ListOperationOptions for the supported + // functionalities. + optional ListOperationOptions options = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetExecutionsResponse { + // Returned executions. + repeated Execution executions = 1; + + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; +} + +message GetArtifactTypeRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name with default type_version. + optional string type_version = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; +} + +message GetArtifactTypeResponse { + // Gets an artifact type, or clear if it does not exist. + optional ArtifactType artifact_type = 1; +} + +message GetArtifactTypesRequest { + // Options regarding transactions. + optional TransactionOptions transaction_options = 1; +} + +message GetArtifactTypesResponse { + repeated ArtifactType artifact_types = 1; +} + +message GetExecutionTypesRequest { + // Options regarding transactions. + optional TransactionOptions transaction_options = 1; +} + +message GetExecutionTypesResponse { + repeated ExecutionType execution_types = 1; +} + +message GetContextTypesRequest { + // Options regarding transactions. + optional TransactionOptions transaction_options = 1; +} + +message GetContextTypesResponse { + repeated ContextType context_types = 1; +} + +message GetArtifactsByExternalIdsRequest { + repeated string external_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetArtifactsByExternalIdsResponse { + repeated Artifact artifacts = 1; +} + +message GetExecutionsByExternalIdsRequest { + repeated string external_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetExecutionsByExternalIdsResponse { + repeated Execution executions = 1; +} + +message GetContextsByExternalIdsRequest { + repeated string external_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetContextsByExternalIdsResponse { + repeated Context contexts = 1; +} + +message GetArtifactTypesByExternalIdsRequest { + repeated string external_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetArtifactTypesByExternalIdsResponse { + repeated ArtifactType artifact_types = 1; +} + +message GetExecutionTypesByExternalIdsRequest { + repeated string external_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetExecutionTypesByExternalIdsResponse { + repeated ExecutionType execution_types = 1; +} + +message GetContextTypesByExternalIdsRequest { + repeated string external_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetContextTypesByExternalIdsResponse { + repeated ContextType context_types = 1; +} + +message GetExecutionsByTypeRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name with default type_version. + optional string type_version = 2; + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + // If set, the request will + // first fetch all executions with specified `type_name` and `type_version`, + // then order by a specifield field + // finally find the correct page and return #Executions of the page size. + // Higher-level APIs may only use the functionalies partially. + // Please reference the API documentation for the API behaviors. + optional ListOperationOptions options = 3; + // Options regarding transactions. + optional TransactionOptions transaction_options = 4; +} + +message GetExecutionsByTypeResponse { + repeated Execution executions = 1; + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; +} + +message GetExecutionByTypeAndNameRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name and execution_name with + // default type_version. + optional string type_version = 3; + optional string execution_name = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 4; +} + +message GetExecutionByTypeAndNameResponse { + optional Execution execution = 1; +} + +message GetExecutionsByIDRequest { + // A list of execution ids to retrieve. + repeated int64 execution_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetExecutionsByIDResponse { + // The result is not index-aligned: if an id is not found, it is not + // returned. + repeated Execution executions = 1; +} + +message GetExecutionTypeRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name with default type_version. + optional string type_version = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; +} + +message GetExecutionTypeResponse { + // Gets an execution type, or clear if it does not exist. + optional ExecutionType execution_type = 1; +} + + +// Gets all events with matching execution ids. +message GetEventsByExecutionIDsRequest { + repeated int64 execution_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetEventsByExecutionIDsResponse { + repeated Event events = 1; +} + +message GetEventsByArtifactIDsRequest { + repeated int64 artifact_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetEventsByArtifactIDsResponse { + repeated Event events = 1; +} + +message GetArtifactTypesByIDRequest { + repeated int64 type_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetArtifactTypesByIDResponse { + // The result is not index-aligned: if an id is not found, it is not + // returned. + repeated ArtifactType artifact_types = 1; +} + +message GetExecutionTypesByIDRequest { + repeated int64 type_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetExecutionTypesByIDResponse { + // The result is not index-aligned: if an id is not found, it is not + // returned. + repeated ExecutionType execution_types = 1; +} + +message GetContextTypeRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name with default type_version. + optional string type_version = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; +} + +message GetContextTypeResponse { + // Gets a context type, or clear if it does not exist. + optional ContextType context_type = 1; +} + +message GetContextTypesByIDRequest { + repeated int64 type_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetContextTypesByIDResponse { + // The result is not index-aligned: if an id is not found, it is not + // returned. + repeated ContextType context_types = 1; +} + +// Request to retrieve Contexts using List options. +// If option is not specified then all Contexts are returned. +message GetContextsRequest { + // Specify options. + // Please refer to the documentation of ListOperationOptions for the supported + // functionalities. + optional ListOperationOptions options = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetContextsResponse { + // Returned contexts. + repeated Context contexts = 1; + + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; +} + +message GetContextsByTypeRequest { + optional string type_name = 1; + // Specify options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + // If set, the request will + // first fetch all contexts with specified `type_name` and `type_version`, + // then order by a specifield field + // finally find the correct page and return #Contexts of the page size. + // Higher-level APIs may only use the functionalies partially. + // Please reference the API documentation for the API behaviors. + optional ListOperationOptions options = 2; + // If not set, it looks for the type with type_name and options with default + // type_version. + optional string type_version = 3; + // Options regarding transactions. + optional TransactionOptions transaction_options = 4; +} + +message GetContextsByTypeResponse { + repeated Context contexts = 1; + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; +} + +message GetContextByTypeAndNameRequest { + optional string type_name = 1; + // If not set, it looks for the type with type_name and context_name with + // default type_version. + optional string type_version = 3; + optional string context_name = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 4; +} + +message GetContextByTypeAndNameResponse { + optional Context context = 1; +} + +message GetContextsByIDRequest { + // A list of context ids to retrieve. + repeated int64 context_ids = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetContextsByIDResponse { + // The result is not index-aligned: if an id is not found, it is not + // returned. + repeated Context contexts = 1; +} + +message GetContextsByArtifactRequest { + optional int64 artifact_id = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetContextsByArtifactResponse { + repeated Context contexts = 1; +} + +message GetContextsByExecutionRequest { + optional int64 execution_id = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetContextsByExecutionResponse { + repeated Context contexts = 1; +} + +message GetParentContextsByContextRequest { + optional int64 context_id = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetParentContextsByContextResponse { + repeated Context contexts = 1; +} + +message GetChildrenContextsByContextRequest { + optional int64 context_id = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetChildrenContextsByContextResponse { + repeated Context contexts = 1; +} + +message GetParentContextsByContextsRequest { + repeated int64 context_ids = 1 [packed = true]; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetParentContextsByContextsResponse { + message ParentContextsPerChild { + repeated Context parent_contexts = 1; + } + map contexts = 2; +} + +message GetChildrenContextsByContextsRequest { + repeated int64 context_ids = 1 [packed = true]; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +message GetChildrenContextsByContextsResponse { + message ChildrenContextsPerParent { + repeated Context children_contexts = 1; + } + map contexts = 2; +} + +message GetArtifactsByContextRequest { + optional int64 context_id = 1; + + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + optional ListOperationOptions options = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; +} + +message GetArtifactsByContextResponse { + repeated Artifact artifacts = 1; + + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; +} + +message GetExecutionsByContextRequest { + optional int64 context_id = 1; + + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + optional ListOperationOptions options = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; +} + +message GetExecutionsByContextResponse { + repeated Execution executions = 1; + + // Token to use to retrieve next page of results if list options are used in + // the request. + optional string next_page_token = 2; + // Options regarding transactions. + optional TransactionOptions transaction_options = 3; +} + + +// TODO(b/283852485): Deprecate GetLineageGraph API after migration to +// GetLineageSubgraph API. +// A lineage query request to specify the query nodes of interest and the +// boundary conditions for pruning the returned graph. +message GetLineageGraphRequest { + optional LineageGraphQueryOptions options = 1; + // Options regarding transactions. + optional TransactionOptions transaction_options = 2; +} + +// A connected lineage `subgraph` about the MLMD nodes derived from +// LineageGraphRequest.query_conditions. +message GetLineageGraphResponse { + optional LineageGraph subgraph = 1; +} + +message GetLineageSubgraphRequest { + // Query options for lineage graph tracing from a list of interested + // nodes. + // A lineage subgraph without node details (e.g., external_id, properties) + // will be returned. Please refer to `LineageSubgraphQueryOptions` for more + // details. + optional LineageSubgraphQueryOptions lineage_subgraph_query_options = 1; + // `read_mask` contains user specified paths of fields that should be included + // in the returned lineage subgraph. + // Supported field paths are: 'artifacts', 'executions', 'contexts', + // 'artifact_types', 'execution_types', 'context_types', and 'events'. + // TODO(b/283852485): Include 'associations' or 'attributions' in the + // returned graph. + // If 'artifacts', 'executions', or 'contexts' is specified in `read_mask`, + // the dehydrated nodes will be included. + // Note: A dehydrated node means a node containing only its id and no + // other information. User should call GetNodesByID or other APIs to get + // node details later on. + // If 'artifact_types', 'execution_types', or 'context_types' is specified + // in `read_mask`, all the node types will be included. + // If 'events' is specified in `read_mask`, the events will be included. + // If `read_mask` is not set, the API will return all the fields in + // the returned graph. + // Note: Only paths of fields in LineageGraph message are supported. Paths + // of fields in the submessage, such as "artifacts.id", "contexts.name" are + // not acknowledged. + optional google.protobuf.FieldMask read_mask = 3; + optional TransactionOptions transaction_options = 2; +} + +message GetLineageSubgraphResponse { + // A lineage subgraph of MLMD nodes and relations retrieved from lineage + // graph tracing. + optional LineageGraph lineage_subgraph = 1; +} + + + +// LINT.IfChange +service MetadataStoreService { + // Inserts or updates an ArtifactType. + // + // A type has a set of strong typed properties describing the schema of any + // stored instance associated with that type. A type is identified by a name + // and an optional version. + // + // Type Creation: + // If no type exists in the database with the given identifier + // (name, version), it creates a new type and returns the type_id. + // + // Type Evolution: + // If the request type with the same (name, version) already exists + // (let's call it stored_type), the method enforces the stored_type can be + // updated only when the request type is backward compatible for the already + // stored instances. + // + // Backwards compatibility is violated iff: + // + // a) there is a property where the request type and stored_type have + // different value type (e.g., int vs. string) + // b) `can_add_fields = false` and the request type has a new property that + // is not stored. + // c) `can_omit_fields = false` and stored_type has an existing property + // that is not provided in the request type. + // + // If non-backward type change is required in the application, e.g., + // deprecate properties, re-purpose property name, change value types, + // a new type can be created with a different (name, version) identifier. + // Note the type version is optional, and a version value with empty string + // is treated as unset. + // + // Args: + // artifact_type: the type to be inserted or updated. + // can_add_fields: + // when set to true, new properties can be added; + // when set to false, returns ALREADY_EXISTS if the request type has + // properties that are not in stored_type. + // can_omit_fields: + // when set to true, stored properties can be omitted in the request type; + // when set to false, returns ALREADY_EXISTS if the stored_type has + // properties not in the request type. + // + // Returns: + // The type_id of the stored type. + // + // Raises: + // ALREADY_EXISTS error in the case listed above. + // INVALID_ARGUMENT error, if the given type has no name, or any + // property value type is unknown. + rpc PutArtifactType(PutArtifactTypeRequest) + returns (PutArtifactTypeResponse) {} + + // Inserts or updates an ExecutionType. Please refer to PutArtifactType for + // type upsert API description. + rpc PutExecutionType(PutExecutionTypeRequest) + returns (PutExecutionTypeResponse) {} + + // Inserts or updates an ContextType. Please refer to PutArtifactType for + // type upsert API description. + rpc PutContextType(PutContextTypeRequest) returns (PutContextTypeResponse) {} + + // Bulk inserts types atomically. + rpc PutTypes(PutTypesRequest) returns (PutTypesResponse) {} + + // Inserts or updates artifacts in the database. + // + // If an artifact_id is specified for an artifact, it is an update. + // If an artifact_id is unspecified, it will insert a new artifact. + // For new artifacts, type must be specified. + // For old artifacts, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated artifacts will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // artifacts: A list of artifacts to insert or update. + // + // Returns: + // A list of artifact ids index-aligned with the input. + rpc PutArtifacts(PutArtifactsRequest) returns (PutArtifactsResponse) {} + + // Inserts or updates executions in the database. + // + // If an execution_id is specified for an execution, it is an update. + // If an execution_id is unspecified, it will insert a new execution. + // For new executions, type must be specified. + // For old executions, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated executions will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // executions: A list of executions to insert or update. + // + // Returns: + // A list of execution ids index-aligned with the input. + // + rpc PutExecutions(PutExecutionsRequest) returns (PutExecutionsResponse) {} + + // Inserts events in the database. + // + // The execution_id and artifact_id must already exist. + // Once created, events cannot be modified. + // AlreadyExists error will be raised if duplicated events are found. + // + // It is not guaranteed that the created or updated events will share the + // same `milliseconds_since_epoch` timestamps. + // + // Args: + // events: A list of events to insert or update. + rpc PutEvents(PutEventsRequest) returns (PutEventsResponse) {} + + // Inserts or updates an Execution and its input and output artifacts and + // related contexts atomically. The `artifact_event_pairs` include the state + // changes of the Artifacts used or generated by the Execution, as well as the + // input/output Event. The `contexts` describe the associations of the + // execution and the attributions of the artifacts. + // + // If an execution_id is specified, it is an update on the corresponding + // execution, otherwise it does an insertion. + // For insertion, type must be specified. Same rule applies to artifacts + // and contexts in the request. Corresponding errors may raised. For example: + // AlreadyExists error will be raised if duplicated executions, artifacts + // or events are found. + // + // It is not guaranteed that the created or updated executions, artifacts, + // contexts and events will share the same `create_time_since_epoch`, + // `last_update_time_since_epoch`, or `milliseconds_since_epoch` timestamps. + // + // Args: + // execution: An execution to insert or update. + // artifact_event_pairs: Artifacts to insert or update and events to insert. + // contexts: The contexts that the execution and the artifacts belong to. + // + // Returns: + // An execution id and a list of artifacts and contexts ids index-aligned + // with the input. + rpc PutExecution(PutExecutionRequest) returns (PutExecutionResponse) {} + + // Inserts or updates a lineage subgraph (i.e. a collection of event edges + // and its executions, artifacts, and related contexts) atomically. The + // `event_edges` include an Event and the indices of the corresponding + // execution and artifact from the input list of executions and artifacts. The + // `contexts` describe the associations of the Execution and the attributions + // of the Artifact. + // + // If an execution_id is specified, it is an update on the corresponding + // Execution, otherwise it does an insertion. For insertion, type must be + // specified. These rules apply to Artifacts and Contexts as well. + // Corresponding errors may be raised. For example: AlreadyExists error will + // be raised if duplicated executions, artifacts, or events are found. + // + // It is not guaranteed that the created or updated executions, artifacts, + // contexts and events will share the same `create_time_since_epoch`, + // `last_update_time_since_epoch`, or `milliseconds_since_epoch` timestamps. + // + // Args: + // executions: A list of executions to insert or update. + // artifacts: A list of artifacts to insert or update. + // contexts: A list of contexts to insert and/or create associations and + // attributions with. + // event_edges: A list of events to insert with the indices of the + // corresponding execution and artifact from the input lists of + // executions and artifacts. + // + // Returns: + // Lists of execution, artifact, and context ids index-aligned with the + // inputs. + rpc PutLineageSubgraph(PutLineageSubgraphRequest) + returns (PutLineageSubgraphResponse) {} + + // Inserts or updates contexts in database and returns a list of context ids. + // + // If an context_id is specified for a context, it is an update. + // If an context_id is unspecified, it will insert a new context. + // For new contexts, type must be specified. + // For old contexts, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated contexts will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // contexts: A list of contexts to insert or update. + // + // Returns: + // A list of context ids index-aligned with the input. + rpc PutContexts(PutContextsRequest) returns (PutContextsResponse) {} + + // Inserts attribution and association relationships in the database. + // The context_id, artifact_id, and execution_id must already exist. + // If the relationship exists, this call does nothing. Once added, the + // relationships cannot be modified. + // + // Args: + // attributions: A list of attributions to insert. + // associations: A list of associations to insert. + rpc PutAttributionsAndAssociations(PutAttributionsAndAssociationsRequest) + returns (PutAttributionsAndAssociationsResponse) {} + + // Inserts parental context relationships in the database. + // The ParentContext relationship has direction. The call fails if cycles are + // detected. + // + // Args: + // parent_contexts: A list of parent contexts to insert. + rpc PutParentContexts(PutParentContextsRequest) + returns (PutParentContextsResponse) {} + + // Gets an artifact type. Returns a NOT_FOUND error if the type does not + // exist. + rpc GetArtifactType(GetArtifactTypeRequest) + returns (GetArtifactTypeResponse) {} + + // Gets a list of artifact types by ID. + // If no artifact types with an ID exists, the artifact type is skipped. + rpc GetArtifactTypesByID(GetArtifactTypesByIDRequest) + returns (GetArtifactTypesByIDResponse) {} + + // Gets a list of all artifact types. + rpc GetArtifactTypes(GetArtifactTypesRequest) + returns (GetArtifactTypesResponse) {} + + // Gets an execution type, or None if it does not exist. + rpc GetExecutionType(GetExecutionTypeRequest) + returns (GetExecutionTypeResponse) {} + + // Gets a list of execution types by ID. + // If no execution types with an ID exists, the execution type is skipped. + rpc GetExecutionTypesByID(GetExecutionTypesByIDRequest) + returns (GetExecutionTypesByIDResponse) {} + + // Gets a list of all execution types. + rpc GetExecutionTypes(GetExecutionTypesRequest) + returns (GetExecutionTypesResponse) {} + + // Gets a context type. Returns a NOT_FOUND error if the type does not exist. + rpc GetContextType(GetContextTypeRequest) returns (GetContextTypeResponse) {} + + // Gets a list of context types by ID. + // If no context types with an ID exists, the context type is skipped. + rpc GetContextTypesByID(GetContextTypesByIDRequest) + returns (GetContextTypesByIDResponse) {} + + // Gets a list of all context types. + rpc GetContextTypes(GetContextTypesRequest) + returns (GetContextTypesResponse) {} + + // Gets all the artifacts. + rpc GetArtifacts(GetArtifactsRequest) returns (GetArtifactsResponse) {} + + // Gets all the executions. + rpc GetExecutions(GetExecutionsRequest) returns (GetExecutionsResponse) {} + + // Gets all the contexts. + rpc GetContexts(GetContextsRequest) returns (GetContextsResponse) {} + + // Gets all artifacts with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // artifact_ids: A list of artifact ids to retrieve. + // + // Returns: + // Artifacts with matching ids. + rpc GetArtifactsByID(GetArtifactsByIDRequest) + returns (GetArtifactsByIDResponse) {} + + // Gets all executions with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // execution_ids: A list of execution ids to retrieve. + rpc GetExecutionsByID(GetExecutionsByIDRequest) + returns (GetExecutionsByIDResponse) {} + + // Gets all contexts with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // context_ids: A list of context ids to retrieve. + rpc GetContextsByID(GetContextsByIDRequest) + returns (GetContextsByIDResponse) {} + + // Gets all the artifacts of a given type. + rpc GetArtifactsByType(GetArtifactsByTypeRequest) + returns (GetArtifactsByTypeResponse) {} + + // Gets all the executions of a given type. + rpc GetExecutionsByType(GetExecutionsByTypeRequest) + returns (GetExecutionsByTypeResponse) {} + + // Gets all the contexts of a given type. + rpc GetContextsByType(GetContextsByTypeRequest) + returns (GetContextsByTypeResponse) {} + + // Gets the artifact of the given type and artifact name. + rpc GetArtifactByTypeAndName(GetArtifactByTypeAndNameRequest) + returns (GetArtifactByTypeAndNameResponse) {} + + // Gets the execution of the given type and execution name. + rpc GetExecutionByTypeAndName(GetExecutionByTypeAndNameRequest) + returns (GetExecutionByTypeAndNameResponse) {} + + // Gets the context of the given type and context name. + rpc GetContextByTypeAndName(GetContextByTypeAndNameRequest) + returns (GetContextByTypeAndNameResponse) {} + + // Gets all the artifacts with matching uris. + rpc GetArtifactsByURI(GetArtifactsByURIRequest) + returns (GetArtifactsByURIResponse) {} + + // Gets all events with matching execution ids. + rpc GetEventsByExecutionIDs(GetEventsByExecutionIDsRequest) + returns (GetEventsByExecutionIDsResponse) {} + + // Gets all events with matching artifact ids. + rpc GetEventsByArtifactIDs(GetEventsByArtifactIDsRequest) + returns (GetEventsByArtifactIDsResponse) {} + + // Gets all the artifacts with matching external ids. + rpc GetArtifactsByExternalIds(GetArtifactsByExternalIdsRequest) + returns (GetArtifactsByExternalIdsResponse) {} + + // Gets all the artifacts with matching external ids. + rpc GetExecutionsByExternalIds(GetExecutionsByExternalIdsRequest) + returns (GetExecutionsByExternalIdsResponse) {} + + // Gets all the artifacts with matching external ids. + rpc GetContextsByExternalIds(GetContextsByExternalIdsRequest) + returns (GetContextsByExternalIdsResponse) {} + + // Gets all the artifacts with matching external ids. + rpc GetArtifactTypesByExternalIds(GetArtifactTypesByExternalIdsRequest) + returns (GetArtifactTypesByExternalIdsResponse) {} + + // Gets all the artifacts with matching external ids. + rpc GetExecutionTypesByExternalIds(GetExecutionTypesByExternalIdsRequest) + returns (GetExecutionTypesByExternalIdsResponse) {} + + // Gets all the artifacts with matching external ids. + rpc GetContextTypesByExternalIds(GetContextTypesByExternalIdsRequest) + returns (GetContextTypesByExternalIdsResponse) {} + + + // Gets all context that an artifact is attributed to. + rpc GetContextsByArtifact(GetContextsByArtifactRequest) + returns (GetContextsByArtifactResponse) {} + + // Gets all context that an execution is associated with. + rpc GetContextsByExecution(GetContextsByExecutionRequest) + returns (GetContextsByExecutionResponse) {} + + // Gets all parent contexts that a context is related. + rpc GetParentContextsByContext(GetParentContextsByContextRequest) + returns (GetParentContextsByContextResponse) {} + + // Gets all children contexts that a context is related. + rpc GetChildrenContextsByContext(GetChildrenContextsByContextRequest) + returns (GetChildrenContextsByContextResponse) {} + + // Batch getting all the parent contexts that a list of contexts are related. + rpc GetParentContextsByContexts(GetParentContextsByContextsRequest) + returns (GetParentContextsByContextsResponse) {} + + // Batch getting all the children contexts that a list of contexts are + // related. + rpc GetChildrenContextsByContexts(GetChildrenContextsByContextsRequest) + returns (GetChildrenContextsByContextsResponse) {} + + // Gets all direct artifacts that a context attributes to. + rpc GetArtifactsByContext(GetArtifactsByContextRequest) + returns (GetArtifactsByContextResponse) {} + + // Gets all direct executions that a context associates with. + rpc GetExecutionsByContext(GetExecutionsByContextRequest) + returns (GetExecutionsByContextResponse) {} + + + // TODO(b/283852485): Deprecate GetLineageGraph API after migration to + // GetLineageSubgraph API. + // The transaction performs a constrained transitive closure and returns a + // lineage subgraph satisfying the conditions and constraints specified in + // the GetLineageGraphRequest. + rpc GetLineageGraph(GetLineageGraphRequest) + returns (GetLineageGraphResponse) {} + + // Gets a lineage subgraph by performing graph traversal from a list of + // interested nodes. + // A lineage subgraph without node details (e.g., external_id, properties) + // will be returned. + rpc GetLineageSubgraph(GetLineageSubgraphRequest) + returns (GetLineageSubgraphResponse) {} + + +} +// LINT.ThenChange(../metadata_store/metadata_store_service_interface.h) diff --git a/model/db/artifact.gen.go b/model/db/artifact.gen.go new file mode 100644 index 00000000..711deaf4 --- /dev/null +++ b/model/db/artifact.gen.go @@ -0,0 +1,24 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameArtifact = "Artifact" + +// Artifact mapped from table +type Artifact struct { + ID int32 `gorm:"column:id;primaryKey" json:"-"` + TypeID int32 `gorm:"column:type_id;not null" json:"-"` + URI string `gorm:"column:uri;not null" json:"-"` + State int32 `gorm:"column:state;not null" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + ExternalID string `gorm:"column:external_id;not null" json:"-"` + CreateTimeSinceEpoch int32 `gorm:"column:create_time_since_epoch;not null" json:"-"` + LastUpdateTimeSinceEpoch int32 `gorm:"column:last_update_time_since_epoch;not null" json:"-"` +} + +// TableName Artifact's table name +func (*Artifact) TableName() string { + return TableNameArtifact +} diff --git a/model/db/artifactproperty.gen.go b/model/db/artifactproperty.gen.go new file mode 100644 index 00000000..6c962d79 --- /dev/null +++ b/model/db/artifactproperty.gen.go @@ -0,0 +1,25 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameArtifactProperty = "ArtifactProperty" + +// ArtifactProperty mapped from table +type ArtifactProperty struct { + ArtifactID int32 `gorm:"column:artifact_id;primaryKey" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` + IntValue int32 `gorm:"column:int_value;not null" json:"-"` + DoubleValue float64 `gorm:"column:double_value;not null" json:"-"` + StringValue string `gorm:"column:string_value;not null" json:"-"` + ByteValue []byte `gorm:"column:byte_value;not null" json:"-"` + ProtoValue []byte `gorm:"column:proto_value;not null" json:"-"` + BoolValue bool `gorm:"column:bool_value;not null" json:"-"` +} + +// TableName ArtifactProperty's table name +func (*ArtifactProperty) TableName() string { + return TableNameArtifactProperty +} diff --git a/model/db/association.gen.go b/model/db/association.gen.go new file mode 100644 index 00000000..81c7fd95 --- /dev/null +++ b/model/db/association.gen.go @@ -0,0 +1,19 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameAssociation = "Association" + +// Association mapped from table +type Association struct { + ID int32 `gorm:"column:id;primaryKey" json:"-"` + ContextID int32 `gorm:"column:context_id;not null" json:"-"` + ExecutionID int32 `gorm:"column:execution_id;not null" json:"-"` +} + +// TableName Association's table name +func (*Association) TableName() string { + return TableNameAssociation +} diff --git a/model/db/attribution.gen.go b/model/db/attribution.gen.go new file mode 100644 index 00000000..65ff7718 --- /dev/null +++ b/model/db/attribution.gen.go @@ -0,0 +1,19 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameAttribution = "Attribution" + +// Attribution mapped from table +type Attribution struct { + ID int32 `gorm:"column:id;primaryKey" json:"-"` + ContextID int32 `gorm:"column:context_id;not null" json:"-"` + ArtifactID int32 `gorm:"column:artifact_id;not null" json:"-"` +} + +// TableName Attribution's table name +func (*Attribution) TableName() string { + return TableNameAttribution +} diff --git a/model/db/context.gen.go b/model/db/context.gen.go new file mode 100644 index 00000000..a4d51d56 --- /dev/null +++ b/model/db/context.gen.go @@ -0,0 +1,22 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameContext = "Context" + +// Context mapped from table +type Context struct { + ID int32 `gorm:"column:id;primaryKey" json:"-"` + TypeID int32 `gorm:"column:type_id;not null" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + ExternalID string `gorm:"column:external_id;not null" json:"-"` + CreateTimeSinceEpoch int32 `gorm:"column:create_time_since_epoch;not null" json:"-"` + LastUpdateTimeSinceEpoch int32 `gorm:"column:last_update_time_since_epoch;not null" json:"-"` +} + +// TableName Context's table name +func (*Context) TableName() string { + return TableNameContext +} diff --git a/model/db/contextproperty.gen.go b/model/db/contextproperty.gen.go new file mode 100644 index 00000000..0b739967 --- /dev/null +++ b/model/db/contextproperty.gen.go @@ -0,0 +1,25 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameContextProperty = "ContextProperty" + +// ContextProperty mapped from table +type ContextProperty struct { + ContextID int32 `gorm:"column:context_id;primaryKey" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` + IntValue int32 `gorm:"column:int_value;not null" json:"-"` + DoubleValue float64 `gorm:"column:double_value;not null" json:"-"` + StringValue string `gorm:"column:string_value;not null" json:"-"` + ByteValue []byte `gorm:"column:byte_value;not null" json:"-"` + ProtoValue []byte `gorm:"column:proto_value;not null" json:"-"` + BoolValue bool `gorm:"column:bool_value;not null" json:"-"` +} + +// TableName ContextProperty's table name +func (*ContextProperty) TableName() string { + return TableNameContextProperty +} diff --git a/model/db/event.gen.go b/model/db/event.gen.go new file mode 100644 index 00000000..be53b3eb --- /dev/null +++ b/model/db/event.gen.go @@ -0,0 +1,21 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameEvent = "Event" + +// Event mapped from table +type Event struct { + ID int32 `gorm:"column:id;primaryKey" json:"-"` + ArtifactID int32 `gorm:"column:artifact_id;not null" json:"-"` + ExecutionID int32 `gorm:"column:execution_id;not null" json:"-"` + Type int32 `gorm:"column:type;not null" json:"-"` + MillisecondsSinceEpoch int32 `gorm:"column:milliseconds_since_epoch;not null" json:"-"` +} + +// TableName Event's table name +func (*Event) TableName() string { + return TableNameEvent +} diff --git a/model/db/eventpath.gen.go b/model/db/eventpath.gen.go new file mode 100644 index 00000000..18f31430 --- /dev/null +++ b/model/db/eventpath.gen.go @@ -0,0 +1,20 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameEventPath = "EventPath" + +// EventPath mapped from table +type EventPath struct { + EventID int32 `gorm:"column:event_id;not null" json:"-"` + IsIndexStep int32 `gorm:"column:is_index_step;not null" json:"-"` + StepIndex int32 `gorm:"column:step_index;not null" json:"-"` + StepKey string `gorm:"column:step_key;not null" json:"-"` +} + +// TableName EventPath's table name +func (*EventPath) TableName() string { + return TableNameEventPath +} diff --git a/model/db/execution.gen.go b/model/db/execution.gen.go new file mode 100644 index 00000000..6c5fb19f --- /dev/null +++ b/model/db/execution.gen.go @@ -0,0 +1,23 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameExecution = "Execution" + +// Execution mapped from table +type Execution struct { + ID int32 `gorm:"column:id;primaryKey" json:"-"` + TypeID int32 `gorm:"column:type_id;not null" json:"-"` + LastKnownState int32 `gorm:"column:last_known_state;not null" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + ExternalID string `gorm:"column:external_id;not null" json:"-"` + CreateTimeSinceEpoch int32 `gorm:"column:create_time_since_epoch;not null" json:"-"` + LastUpdateTimeSinceEpoch int32 `gorm:"column:last_update_time_since_epoch;not null" json:"-"` +} + +// TableName Execution's table name +func (*Execution) TableName() string { + return TableNameExecution +} diff --git a/model/db/executionproperty.gen.go b/model/db/executionproperty.gen.go new file mode 100644 index 00000000..74f851bf --- /dev/null +++ b/model/db/executionproperty.gen.go @@ -0,0 +1,25 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameExecutionProperty = "ExecutionProperty" + +// ExecutionProperty mapped from table +type ExecutionProperty struct { + ExecutionID int32 `gorm:"column:execution_id;primaryKey" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` + IntValue int32 `gorm:"column:int_value;not null" json:"-"` + DoubleValue float64 `gorm:"column:double_value;not null" json:"-"` + StringValue string `gorm:"column:string_value;not null" json:"-"` + ByteValue []byte `gorm:"column:byte_value;not null" json:"-"` + ProtoValue []byte `gorm:"column:proto_value;not null" json:"-"` + BoolValue bool `gorm:"column:bool_value;not null" json:"-"` +} + +// TableName ExecutionProperty's table name +func (*ExecutionProperty) TableName() string { + return TableNameExecutionProperty +} diff --git a/model/db/mlmdenv.gen.go b/model/db/mlmdenv.gen.go new file mode 100644 index 00000000..8941d513 --- /dev/null +++ b/model/db/mlmdenv.gen.go @@ -0,0 +1,17 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameMLMDEnv = "MLMDEnv" + +// MLMDEnv mapped from table +type MLMDEnv struct { + SchemaVersion int32 `gorm:"column:schema_version;primaryKey" json:"-"` +} + +// TableName MLMDEnv's table name +func (*MLMDEnv) TableName() string { + return TableNameMLMDEnv +} diff --git a/model/db/parentcontext.gen.go b/model/db/parentcontext.gen.go new file mode 100644 index 00000000..002f90eb --- /dev/null +++ b/model/db/parentcontext.gen.go @@ -0,0 +1,18 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameParentContext = "ParentContext" + +// ParentContext mapped from table +type ParentContext struct { + ContextID int32 `gorm:"column:context_id;primaryKey" json:"-"` + ParentContextID int32 `gorm:"column:parent_context_id;not null" json:"-"` +} + +// TableName ParentContext's table name +func (*ParentContext) TableName() string { + return TableNameParentContext +} diff --git a/model/db/parenttype.gen.go b/model/db/parenttype.gen.go new file mode 100644 index 00000000..9a287a7a --- /dev/null +++ b/model/db/parenttype.gen.go @@ -0,0 +1,18 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameParentType = "ParentType" + +// ParentType mapped from table +type ParentType struct { + TypeID int32 `gorm:"column:type_id;primaryKey" json:"-"` + ParentTypeID int32 `gorm:"column:parent_type_id;not null" json:"-"` +} + +// TableName ParentType's table name +func (*ParentType) TableName() string { + return TableNameParentType +} diff --git a/model/db/type.gen.go b/model/db/type.gen.go new file mode 100644 index 00000000..5179d952 --- /dev/null +++ b/model/db/type.gen.go @@ -0,0 +1,24 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameType = "Type" + +// Type mapped from table +type Type struct { + ID int32 `gorm:"column:id;primaryKey" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + Version string `gorm:"column:version;not null" json:"-"` + TypeKind int32 `gorm:"column:type_kind;not null" json:"-"` + Description string `gorm:"column:description;not null" json:"-"` + InputType string `gorm:"column:input_type;not null" json:"-"` + OutputType string `gorm:"column:output_type;not null" json:"-"` + ExternalID string `gorm:"column:external_id;not null" json:"-"` +} + +// TableName Type's table name +func (*Type) TableName() string { + return TableNameType +} diff --git a/model/db/typeproperty.gen.go b/model/db/typeproperty.gen.go new file mode 100644 index 00000000..43d36cec --- /dev/null +++ b/model/db/typeproperty.gen.go @@ -0,0 +1,19 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameTypeProperty = "TypeProperty" + +// TypeProperty mapped from table +type TypeProperty struct { + TypeID int32 `gorm:"column:type_id;primaryKey" json:"-"` + Name string `gorm:"column:name;not null" json:"-"` + DataType *int32 `gorm:"column:data_type" json:"-"` +} + +// TableName TypeProperty's table name +func (*TypeProperty) TableName() string { + return TableNameTypeProperty +} diff --git a/server/db_context.go b/server/db_context.go new file mode 100644 index 00000000..00c19d41 --- /dev/null +++ b/server/db_context.go @@ -0,0 +1,65 @@ +package server + +import ( + "context" + "fmt" + "gorm.io/gorm" +) + +type key int + +var dbKey key + +type txContext struct { + db *gorm.DB + wrapped bool +} + +// NewContext returns a new Context that carries value txContext. +func NewContext(ctx context.Context, db *gorm.DB) context.Context { + ctxDb, ok := FromContext(ctx) + if !ok { + return context.WithValue(ctx, dbKey, &txContext{db.Begin(), false}) + } + return context.WithValue(ctx, dbKey, &txContext{ctxDb, true}) +} + +// FromContext returns the gorm.DB value stored in ctx, if any. +func FromContext(ctx context.Context) (*gorm.DB, bool) { + var result *gorm.DB + tx, ok := ctx.Value(dbKey).(*txContext) + if ok { + result = tx.db + } + return result, ok +} + +func Begin(ctx context.Context, db *gorm.DB) (newCtx context.Context, dbConn *gorm.DB) { + newCtx = NewContext(ctx, db) + dbConn, _ = FromContext(ctx) + return +} + +func Commit(ctx context.Context) error { + tx, ok := ctx.Value(dbKey).(*txContext) + if !ok { + return fmt.Errorf("missing db transaction in context %s", ctx) + } + if !tx.wrapped { + return tx.db.Commit().Error + } + // commit in unwrapped parent context + return nil +} + +func Rollback(ctx context.Context) error { + tx, ok := ctx.Value(dbKey).(*txContext) + if !ok { + return fmt.Errorf("missing db transaction in context %s", ctx) + } + if !tx.wrapped { + return tx.db.Rollback().Error + } + // rollback in unwrapped parent context + return nil +} diff --git a/server/grpc_server.go b/server/grpc_server.go new file mode 100644 index 00000000..c003e00b --- /dev/null +++ b/server/grpc_server.go @@ -0,0 +1,447 @@ +package server + +import ( + "context" + "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" + "github.com/dhirajsb/ml-metadata-go-server/model/db" + "github.com/golang/glog" + "gorm.io/gorm" +) + +type TypeKind int32 + +// artifact type values from ml-metadata table values +const ( + EXECUTION_TYPE TypeKind = iota + ARTIFACT_TYPE + CONTEXT_TYPE +) + +func (tk TypeKind) String() string { + switch tk { + case EXECUTION_TYPE: + return "Execution" + case ARTIFACT_TYPE: + return "Artifact" + case CONTEXT_TYPE: + return "Context" + } + return "unknown" +} + +type grpcServer struct { + proto.UnimplementedMetadataStoreServiceServer + dbConnection *gorm.DB +} + +var _ proto.MetadataStoreServiceServer = grpcServer{} +var _ proto.MetadataStoreServiceServer = (*grpcServer)(nil) + +func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { + return &grpcServer{dbConnection: dbConnection} +} + +func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer closeDbConnection(ctx, &err) + + artifactType := request.GetArtifactType() + name := artifactType.Name + value := &db.Type{ + Name: *name, + Version: *artifactType.Version, + TypeKind: int32(ARTIFACT_TYPE), + Description: *(artifactType.Description), + ExternalID: *(artifactType.ExternalId), + } + if err := dbConn.Create(value).Error; err != nil { + glog.Errorf("error creating artifact type %s: %v", name, err) + return nil, err + } + err = g.createProperties(ctx, request.ArtifactType.Properties, value) + if err != nil { + return nil, err + } + var typeId = int64(value.ID) + return &proto.PutArtifactTypeResponse{ + TypeId: &typeId, + }, nil +} + +func (g grpcServer) createProperties(ctx context.Context, properties map[string]proto.PropertyType, value *db.Type) error { + for propName, prop := range properties { + number := int32(prop.Number()) + property := db.TypeProperty{ + TypeID: value.ID, + Name: propName, + DataType: &number, + } + dbConn, _ := FromContext(ctx) + if err := dbConn.Create(property).Error; err != nil { + glog.Errorf("error creating type property %s: %v", propName, err) + return err + } + } + return nil +} + +func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer closeDbConnection(ctx, &err) + + executionType := request.GetExecutionType() + value := &db.Type{ + Name: *executionType.Name, + Version: *executionType.Version, + TypeKind: int32(EXECUTION_TYPE), + Description: *(executionType.Description), + InputType: executionType.InputType.String(), + OutputType: executionType.OutputType.String(), + ExternalID: *(executionType.ExternalId), + } + if err = dbConn.Create(value).Error; err != nil { + glog.Errorf("error creating execution type %s: %v", executionType.Name, err) + return nil, err + } + err = g.createProperties(ctx, request.ExecutionType.Properties, value) + if err != nil { + return nil, err + } + var typeId = int64(value.ID) + return &proto.PutExecutionTypeResponse{ + TypeId: &typeId, + }, nil +} + +func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer closeDbConnection(ctx, &err) + + contextType := request.ContextType + value := &db.Type{ + Name: *contextType.Name, + Version: *contextType.Version, + TypeKind: int32(CONTEXT_TYPE), + Description: *(contextType.Description), + ExternalID: *(contextType.ExternalId), + } + if err := dbConn.Create(value).Error; err != nil { + glog.Errorf("error creating type %s: %v", contextType.Name, err) + return nil, err + } + err = g.createProperties(ctx, request.ContextType.Properties, value) + if err != nil { + return nil, err + } + var typeId = int64(value.ID) + return &proto.PutContextTypeResponse{ + TypeId: &typeId, + }, nil +} + +func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest) (resp *proto.PutTypesResponse, err error) { + ctx, _ = Begin(ctx, g.dbConnection) + defer closeDbConnection(ctx, &err) + + response := &proto.PutTypesResponse{} + + for _, ar := range request.ArtifactTypes { + var at *proto.PutArtifactTypeResponse + at, err = g.PutArtifactType(ctx, &proto.PutArtifactTypeRequest{ + ArtifactType: ar, + CanAddFields: request.CanAddFields, + CanOmitFields: request.CanOmitFields, + CanDeleteFields: request.CanDeleteFields, + AllFieldsMatch: request.AllFieldsMatch, + TransactionOptions: request.TransactionOptions, + }) + if err != nil { + return response, err + } + response.ArtifactTypeIds = append(response.ArtifactTypeIds, *at.TypeId) + } + for _, ex := range request.ExecutionTypes { + var er *proto.PutExecutionTypeResponse + er, err = g.PutExecutionType(ctx, &proto.PutExecutionTypeRequest{ + ExecutionType: ex, + CanAddFields: request.CanAddFields, + CanOmitFields: request.CanOmitFields, + CanDeleteFields: request.CanDeleteFields, + AllFieldsMatch: request.AllFieldsMatch, + TransactionOptions: request.TransactionOptions, + }) + if err != nil { + return response, err + } + response.ExecutionTypeIds = append(response.ExecutionTypeIds, *er.TypeId) + } + for _, ct := range request.ContextTypes { + var cr *proto.PutContextTypeResponse + cr, err = g.PutContextType(ctx, &proto.PutContextTypeRequest{ + ContextType: ct, + CanAddFields: request.CanAddFields, + CanOmitFields: request.CanOmitFields, + CanDeleteFields: request.CanDeleteFields, + AllFieldsMatch: request.AllFieldsMatch, + TransactionOptions: request.TransactionOptions, + }) + if err != nil { + return response, err + } + response.ContextTypeIds = append(response.ContextTypeIds, *cr.TypeId) + } + return response, nil +} + +func closeDbConnection(ctx context.Context, err *error) { + if err == nil || *err == nil { + *err = Commit(ctx) + } else { + _ = Rollback(ctx) + } +} + +func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (*proto.PutArtifactsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) PutExecutions(ctx context.Context, request *proto.PutExecutionsRequest) (*proto.PutExecutionsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) PutEvents(ctx context.Context, request *proto.PutEventsRequest) (*proto.PutEventsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) PutExecution(ctx context.Context, request *proto.PutExecutionRequest) (*proto.PutExecutionResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) PutLineageSubgraph(ctx context.Context, request *proto.PutLineageSubgraphRequest) (*proto.PutLineageSubgraphResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) PutContexts(ctx context.Context, request *proto.PutContextsRequest) (*proto.PutContextsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) PutAttributionsAndAssociations(ctx context.Context, request *proto.PutAttributionsAndAssociationsRequest) (*proto.PutAttributionsAndAssociationsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) PutParentContexts(ctx context.Context, request *proto.PutParentContextsRequest) (*proto.PutParentContextsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (*proto.GetArtifactTypeResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactTypesByID(ctx context.Context, request *proto.GetArtifactTypesByIDRequest) (*proto.GetArtifactTypesByIDResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactTypes(ctx context.Context, request *proto.GetArtifactTypesRequest) (*proto.GetArtifactTypesResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionType(ctx context.Context, request *proto.GetExecutionTypeRequest) (*proto.GetExecutionTypeResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionTypesByID(ctx context.Context, request *proto.GetExecutionTypesByIDRequest) (*proto.GetExecutionTypesByIDResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionTypes(ctx context.Context, request *proto.GetExecutionTypesRequest) (*proto.GetExecutionTypesResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextType(ctx context.Context, request *proto.GetContextTypeRequest) (*proto.GetContextTypeResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextTypesByID(ctx context.Context, request *proto.GetContextTypesByIDRequest) (*proto.GetContextTypesByIDResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextTypes(ctx context.Context, request *proto.GetContextTypesRequest) (*proto.GetContextTypesResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifacts(ctx context.Context, request *proto.GetArtifactsRequest) (*proto.GetArtifactsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutions(ctx context.Context, request *proto.GetExecutionsRequest) (*proto.GetExecutionsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContexts(ctx context.Context, request *proto.GetContextsRequest) (*proto.GetContextsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactsByID(ctx context.Context, request *proto.GetArtifactsByIDRequest) (*proto.GetArtifactsByIDResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionsByID(ctx context.Context, request *proto.GetExecutionsByIDRequest) (*proto.GetExecutionsByIDResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextsByID(ctx context.Context, request *proto.GetContextsByIDRequest) (*proto.GetContextsByIDResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactsByType(ctx context.Context, request *proto.GetArtifactsByTypeRequest) (*proto.GetArtifactsByTypeResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionsByType(ctx context.Context, request *proto.GetExecutionsByTypeRequest) (*proto.GetExecutionsByTypeResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextsByType(ctx context.Context, request *proto.GetContextsByTypeRequest) (*proto.GetContextsByTypeResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactByTypeAndName(ctx context.Context, request *proto.GetArtifactByTypeAndNameRequest) (*proto.GetArtifactByTypeAndNameResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionByTypeAndName(ctx context.Context, request *proto.GetExecutionByTypeAndNameRequest) (*proto.GetExecutionByTypeAndNameResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextByTypeAndName(ctx context.Context, request *proto.GetContextByTypeAndNameRequest) (*proto.GetContextByTypeAndNameResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactsByURI(ctx context.Context, request *proto.GetArtifactsByURIRequest) (*proto.GetArtifactsByURIResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetEventsByExecutionIDs(ctx context.Context, request *proto.GetEventsByExecutionIDsRequest) (*proto.GetEventsByExecutionIDsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetEventsByArtifactIDs(ctx context.Context, request *proto.GetEventsByArtifactIDsRequest) (*proto.GetEventsByArtifactIDsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactsByExternalIds(ctx context.Context, request *proto.GetArtifactsByExternalIdsRequest) (*proto.GetArtifactsByExternalIdsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionsByExternalIds(ctx context.Context, request *proto.GetExecutionsByExternalIdsRequest) (*proto.GetExecutionsByExternalIdsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextsByExternalIds(ctx context.Context, request *proto.GetContextsByExternalIdsRequest) (*proto.GetContextsByExternalIdsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactTypesByExternalIds(ctx context.Context, request *proto.GetArtifactTypesByExternalIdsRequest) (*proto.GetArtifactTypesByExternalIdsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionTypesByExternalIds(ctx context.Context, request *proto.GetExecutionTypesByExternalIdsRequest) (*proto.GetExecutionTypesByExternalIdsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextTypesByExternalIds(ctx context.Context, request *proto.GetContextTypesByExternalIdsRequest) (*proto.GetContextTypesByExternalIdsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextsByArtifact(ctx context.Context, request *proto.GetContextsByArtifactRequest) (*proto.GetContextsByArtifactResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetContextsByExecution(ctx context.Context, request *proto.GetContextsByExecutionRequest) (*proto.GetContextsByExecutionResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetParentContextsByContext(ctx context.Context, request *proto.GetParentContextsByContextRequest) (*proto.GetParentContextsByContextResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetChildrenContextsByContext(ctx context.Context, request *proto.GetChildrenContextsByContextRequest) (*proto.GetChildrenContextsByContextResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetParentContextsByContexts(ctx context.Context, request *proto.GetParentContextsByContextsRequest) (*proto.GetParentContextsByContextsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetChildrenContextsByContexts(ctx context.Context, request *proto.GetChildrenContextsByContextsRequest) (*proto.GetChildrenContextsByContextsResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetArtifactsByContext(ctx context.Context, request *proto.GetArtifactsByContextRequest) (*proto.GetArtifactsByContextResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetExecutionsByContext(ctx context.Context, request *proto.GetExecutionsByContextRequest) (*proto.GetExecutionsByContextResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetLineageGraph(ctx context.Context, request *proto.GetLineageGraphRequest) (*proto.GetLineageGraphResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) GetLineageSubgraph(ctx context.Context, request *proto.GetLineageSubgraphRequest) (*proto.GetLineageSubgraphResponse, error) { + //TODO implement me + panic("implement me") +} + +func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { + //TODO implement me + panic("implement me") +} diff --git a/test/python/test_mlmetadata.py b/test/python/test_mlmetadata.py new file mode 100644 index 00000000..ff4b71bb --- /dev/null +++ b/test/python/test_mlmetadata.py @@ -0,0 +1,146 @@ +import ml_metadata as mlmd +from grpc import insecure_channel +# from ml_metadata.metadata_store import metadata_store +from ml_metadata.proto import metadata_store_pb2 +from ml_metadata.proto import metadata_store_service_pb2_grpc + +# connection_config = metadata_store_pb2.ConnectionConfig() +# connection_config.sqlite.filename_uri = './metadata.sqlite' +# connection_config.sqlite.connection_mode = 3 # READWRITE_OPENCREATE +# store = metadata_store.MetadataStore(connection_config) + +# connection_config = metadata_store_pb2.ConnectionConfig() +# connection_config.mysql.host = 'localhost' +# connection_config.mysql.port = 3306 +# connection_config.mysql.database = 'mlmetadata' +# connection_config.mysql.user = 'root' +# connection_config.mysql.password = 'my-secret-pw' +# store = metadata_store.MetadataStore(connection_config, enable_upgrade_migration=True) + +channel = insecure_channel('localhost:8080') +store = metadata_store_service_pb2_grpc.MetadataStoreServiceStub(channel) + +# Create ArtifactTypes, e.g., Data and Model +data_type = metadata_store_pb2.ArtifactType() +data_type.name = "DataSet" +data_type.properties["day"] = metadata_store_pb2.INT +data_type.properties["split"] = metadata_store_pb2.STRING +data_type_id = store.PutArtifactType(data_type) + +model_type = metadata_store_pb2.ArtifactType() +model_type.name = "SavedModel" +model_type.properties["version"] = metadata_store_pb2.INT +model_type.properties["name"] = metadata_store_pb2.STRING +model_type_id = store.PutArtifactType(model_type) + +# Query all registered Artifact types. +artifact_types = store.GetArtifactTypes() + +# Create an ExecutionType, e.g., Trainer +trainer_type = metadata_store_pb2.ExecutionType() +trainer_type.name = "Trainer" +trainer_type.properties["state"] = metadata_store_pb2.STRING +trainer_type_id = store.PutExecutionType(trainer_type) + +# Query a registered Execution type with the returned id +[registered_type] = store.GetExecutionTypesByID([trainer_type_id]) + +# Create an input artifact of type DataSet +data_artifact = metadata_store_pb2.Artifact() +data_artifact.uri = 'path/to/data' +data_artifact.properties["day"].int_value = 1 +data_artifact.properties["split"].string_value = 'train' +data_artifact.type_id = data_type_id +[data_artifact_id] = store.PutArtifacts([data_artifact]) + +# Query all registered Artifacts +artifacts = store.GetArtifacts() + +# Plus, there are many ways to query the same Artifact +[stored_data_artifact] = store.GetArtifactsByID([data_artifact_id]) +artifacts_with_uri = store.GetArtifactsByURI(data_artifact.uri) +artifacts_with_conditions = store.GetArtifacts( + list_options=mlmd.ListOptions( + filter_query='uri LIKE "%/data" AND properties.day.int_value > 0')) + +# Register the Execution of a Trainer run +trainer_run = metadata_store_pb2.Execution() +trainer_run.type_id = trainer_type_id +trainer_run.properties["state"].string_value = "RUNNING" +[run_id] = store.PutExecutions([trainer_run]) + +# Query all registered Execution +executions = store.GetExecutionsByID([run_id]) +# Similarly, the same execution can be queried with conditions. +executions_with_conditions = store.GetExecutions( + list_options = mlmd.ListOptions( + filter_query='type = "Trainer" AND properties.state.string_value IS NOT NULL')) + +# Define the input event +input_event = metadata_store_pb2.Event() +input_event.artifact_id = data_artifact_id +input_event.execution_id = run_id +input_event.type = metadata_store_pb2.Event.DECLARED_INPUT + +# Record the input event in the metadata store +store.put_events([input_event]) + +# Declare the output artifact of type SavedModel +model_artifact = metadata_store_pb2.Artifact() +model_artifact.uri = 'path/to/model/file' +model_artifact.properties["version"].int_value = 1 +model_artifact.properties["name"].string_value = 'MNIST-v1' +model_artifact.type_id = model_type_id +[model_artifact_id] = store.PutArtifacts([model_artifact]) + +# Declare the output event +output_event = metadata_store_pb2.Event() +output_event.artifact_id = model_artifact_id +output_event.execution_id = run_id +output_event.type = metadata_store_pb2.Event.DECLARED_OUTPUT + +# Submit output event to the Metadata Store +store.PutEvents([output_event]) + +trainer_run.id = run_id +trainer_run.properties["state"].string_value = "COMPLETED" +store.PutExecutions([trainer_run]) + +# Create a ContextType, e.g., Experiment with a note property +experiment_type = metadata_store_pb2.ContextType() +experiment_type.name = "Experiment" +experiment_type.properties["note"] = metadata_store_pb2.STRING +experiment_type_id = store.PutContextType(experiment_type) + +# Group the model and the trainer run to an experiment. +my_experiment = metadata_store_pb2.Context() +my_experiment.type_id = experiment_type_id +# Give the experiment a name +my_experiment.name = "exp1" +my_experiment.properties["note"].string_value = "My first experiment." +[experiment_id] = store.PutContexts([my_experiment]) + +attribution = metadata_store_pb2.Attribution() +attribution.artifact_id = model_artifact_id +attribution.context_id = experiment_id + +association = metadata_store_pb2.Association() +association.execution_id = run_id +association.context_id = experiment_id + +store.PutAttributionsAndAssociations([attribution], [association]) + +# Query the Artifacts and Executions that are linked to the Context. +experiment_artifacts = store.GetArtifactsByContext(experiment_id) +experiment_executions = store.GetExecutionsByContext(experiment_id) + +# You can also use neighborhood queries to fetch these artifacts and executions +# with conditions. +experiment_artifacts_with_conditions = store.GetArtifacts( + list_options = mlmd.ListOptions( + filter_query=('contexts_a.type = "Experiment" AND contexts_a.name = "exp1"'))) +experiment_executions_with_conditions = store.GetExecutions( + list_options = mlmd.ListOptions( + filter_query=('contexts_a.id = {}'.format(experiment_id)))) + + From 5cfa1511e86c5839bc7305e4b8a5c2ae2bd87ede Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 30 Aug 2023 17:25:51 -0700 Subject: [PATCH 003/254] Added vendor gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 81668d33..4377d252 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ ml-metadata-go-server ml_metadata/proto/*.go metadata.sqlite.db +vendor From 38584140b53903909829c7886bbc54615fca1d8a Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 30 Aug 2023 17:51:10 -0700 Subject: [PATCH 004/254] Added migrate cmd --- Makefile | 3 ++ cmd/migrate.go | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 cmd/migrate.go diff --git a/Makefile b/Makefile index 00e39e4a..a3b61345 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,9 @@ clean: build: gen/grpc go build +run/migrate: gen/grpc + go run main.go migrate + run/server: gen/grpc go run main.go serve diff --git a/cmd/migrate.go b/cmd/migrate.go new file mode 100644 index 00000000..1f1102ec --- /dev/null +++ b/cmd/migrate.go @@ -0,0 +1,81 @@ +/* +Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com + +Licensed 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 cmd + +import ( + "fmt" + "github.com/dhirajsb/ml-metadata-go-server/model/db" + "github.com/golang/glog" + "github.com/spf13/cobra" +) + +// migrateCmd represents the migrate command +var migrateCmd = &cobra.Command{ + Use: "migrate", + Short: "Migrate ml-metadata DB to latest schema", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + RunE: func(cmd *cobra.Command, args []string) error { + // connect to DB + dbConn, err := NewDatabaseConnection(dbFile) + if err != nil { + err = fmt.Errorf("db connection failed: %w", err) + glog.Error(err) + return err + } + // migrate all DB types + err = dbConn.AutoMigrate( + db.Artifact{}, + db.ArtifactProperty{}, + db.Association{}, + db.Attribution{}, + db.Context{}, + db.ContextProperty{}, + db.Event{}, + db.EventPath{}, + db.Execution{}, + db.ExecutionProperty{}, + db.ParentContext{}, + db.ParentType{}, + db.Type{}, + db.TypeProperty{}, + ) + if err != nil { + err = fmt.Errorf("db migration failed: %w", err) + glog.Error(err) + return err + } + return nil + }, +} + +func init() { + rootCmd.AddCommand(migrateCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // migrateCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + migrateCmd.Flags().StringVar(&dbFile, "db-file", "metadata.sqlite.db", "Sqlite DB file") +} From 0c61cc3c4cd91e0165c0898deed698d31224667e Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 30 Aug 2023 18:38:29 -0700 Subject: [PATCH 005/254] Create README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ac92625f..0cc85439 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# model-registry \ No newline at end of file +# ml-metadata-go-server + +A simple go server that implements a gRPC interface for [ml_metadata](https://github.com/google/ml-metadata/) library. From 8b06c752849a21b02baa5b683ce2667f4f25f7fc Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 30 Aug 2023 22:18:08 -0700 Subject: [PATCH 006/254] Working PutArtifactType() for grpcurl -plaintext --- cmd/serve.go | 2 + go.mod | 3 +- go.sum | 2 - server/db_context.go | 2 +- server/grpc_server.go | 20 ++- test/python/test_mlmetadata.py | 282 +++++++++++++++++---------------- 6 files changed, 161 insertions(+), 150 deletions(-) diff --git a/cmd/serve.go b/cmd/serve.go index 4e88ee16..a73312c2 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -24,6 +24,7 @@ import ( "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" "github.com/spf13/cobra" "google.golang.org/grpc" + "google.golang.org/grpc/reflection" "gorm.io/driver/sqlite" "gorm.io/gorm" "log" @@ -96,6 +97,7 @@ to quickly create a Cobra application.`, grpcServer := grpc.NewServer(opts...) proto.RegisterMetadataStoreServiceServer(grpcServer, server.NewGrpcServer(db)) + reflection.Register(grpcServer) var wg sync.WaitGroup wg.Add(1) diff --git a/go.mod b/go.mod index de5b1c8d..0d8f855f 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,9 @@ go 1.19 require ( github.com/golang/glog v1.1.0 - github.com/golang/protobuf v1.5.3 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 - google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 gorm.io/driver/sqlite v1.5.3 @@ -17,6 +15,7 @@ require ( require ( github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect diff --git a/go.sum b/go.sum index c97e0669..9750d540 100644 --- a/go.sum +++ b/go.sum @@ -455,8 +455,6 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= diff --git a/server/db_context.go b/server/db_context.go index 00c19d41..a694df14 100644 --- a/server/db_context.go +++ b/server/db_context.go @@ -36,7 +36,7 @@ func FromContext(ctx context.Context) (*gorm.DB, bool) { func Begin(ctx context.Context, db *gorm.DB) (newCtx context.Context, dbConn *gorm.DB) { newCtx = NewContext(ctx, db) - dbConn, _ = FromContext(ctx) + dbConn, _ = FromContext(newCtx) return } diff --git a/server/grpc_server.go b/server/grpc_server.go index c003e00b..c278d80e 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -2,6 +2,7 @@ package server import ( "context" + "errors" "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" "github.com/dhirajsb/ml-metadata-go-server/model/db" "github.com/golang/glog" @@ -47,12 +48,21 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif artifactType := request.GetArtifactType() name := artifactType.Name + if name == nil { + return nil, errors.New("missing required field name") + } value := &db.Type{ - Name: *name, - Version: *artifactType.Version, - TypeKind: int32(ARTIFACT_TYPE), - Description: *(artifactType.Description), - ExternalID: *(artifactType.ExternalId), + Name: *name, + TypeKind: int32(ARTIFACT_TYPE), + } + if artifactType.Version != nil { + value.Version = *artifactType.Version + } + if artifactType.Description != nil { + value.Description = *artifactType.Description + } + if artifactType.ExternalId != nil { + value.ExternalID = *artifactType.ExternalId } if err := dbConn.Create(value).Error; err != nil { glog.Errorf("error creating artifact type %s: %v", name, err) diff --git a/test/python/test_mlmetadata.py b/test/python/test_mlmetadata.py index ff4b71bb..1779b3e3 100644 --- a/test/python/test_mlmetadata.py +++ b/test/python/test_mlmetadata.py @@ -4,143 +4,145 @@ from ml_metadata.proto import metadata_store_pb2 from ml_metadata.proto import metadata_store_service_pb2_grpc -# connection_config = metadata_store_pb2.ConnectionConfig() -# connection_config.sqlite.filename_uri = './metadata.sqlite' -# connection_config.sqlite.connection_mode = 3 # READWRITE_OPENCREATE -# store = metadata_store.MetadataStore(connection_config) - -# connection_config = metadata_store_pb2.ConnectionConfig() -# connection_config.mysql.host = 'localhost' -# connection_config.mysql.port = 3306 -# connection_config.mysql.database = 'mlmetadata' -# connection_config.mysql.user = 'root' -# connection_config.mysql.password = 'my-secret-pw' -# store = metadata_store.MetadataStore(connection_config, enable_upgrade_migration=True) - -channel = insecure_channel('localhost:8080') -store = metadata_store_service_pb2_grpc.MetadataStoreServiceStub(channel) - -# Create ArtifactTypes, e.g., Data and Model -data_type = metadata_store_pb2.ArtifactType() -data_type.name = "DataSet" -data_type.properties["day"] = metadata_store_pb2.INT -data_type.properties["split"] = metadata_store_pb2.STRING -data_type_id = store.PutArtifactType(data_type) - -model_type = metadata_store_pb2.ArtifactType() -model_type.name = "SavedModel" -model_type.properties["version"] = metadata_store_pb2.INT -model_type.properties["name"] = metadata_store_pb2.STRING -model_type_id = store.PutArtifactType(model_type) - -# Query all registered Artifact types. -artifact_types = store.GetArtifactTypes() - -# Create an ExecutionType, e.g., Trainer -trainer_type = metadata_store_pb2.ExecutionType() -trainer_type.name = "Trainer" -trainer_type.properties["state"] = metadata_store_pb2.STRING -trainer_type_id = store.PutExecutionType(trainer_type) - -# Query a registered Execution type with the returned id -[registered_type] = store.GetExecutionTypesByID([trainer_type_id]) - -# Create an input artifact of type DataSet -data_artifact = metadata_store_pb2.Artifact() -data_artifact.uri = 'path/to/data' -data_artifact.properties["day"].int_value = 1 -data_artifact.properties["split"].string_value = 'train' -data_artifact.type_id = data_type_id -[data_artifact_id] = store.PutArtifacts([data_artifact]) - -# Query all registered Artifacts -artifacts = store.GetArtifacts() - -# Plus, there are many ways to query the same Artifact -[stored_data_artifact] = store.GetArtifactsByID([data_artifact_id]) -artifacts_with_uri = store.GetArtifactsByURI(data_artifact.uri) -artifacts_with_conditions = store.GetArtifacts( - list_options=mlmd.ListOptions( - filter_query='uri LIKE "%/data" AND properties.day.int_value > 0')) - -# Register the Execution of a Trainer run -trainer_run = metadata_store_pb2.Execution() -trainer_run.type_id = trainer_type_id -trainer_run.properties["state"].string_value = "RUNNING" -[run_id] = store.PutExecutions([trainer_run]) - -# Query all registered Execution -executions = store.GetExecutionsByID([run_id]) -# Similarly, the same execution can be queried with conditions. -executions_with_conditions = store.GetExecutions( - list_options = mlmd.ListOptions( - filter_query='type = "Trainer" AND properties.state.string_value IS NOT NULL')) - -# Define the input event -input_event = metadata_store_pb2.Event() -input_event.artifact_id = data_artifact_id -input_event.execution_id = run_id -input_event.type = metadata_store_pb2.Event.DECLARED_INPUT - -# Record the input event in the metadata store -store.put_events([input_event]) - -# Declare the output artifact of type SavedModel -model_artifact = metadata_store_pb2.Artifact() -model_artifact.uri = 'path/to/model/file' -model_artifact.properties["version"].int_value = 1 -model_artifact.properties["name"].string_value = 'MNIST-v1' -model_artifact.type_id = model_type_id -[model_artifact_id] = store.PutArtifacts([model_artifact]) - -# Declare the output event -output_event = metadata_store_pb2.Event() -output_event.artifact_id = model_artifact_id -output_event.execution_id = run_id -output_event.type = metadata_store_pb2.Event.DECLARED_OUTPUT - -# Submit output event to the Metadata Store -store.PutEvents([output_event]) - -trainer_run.id = run_id -trainer_run.properties["state"].string_value = "COMPLETED" -store.PutExecutions([trainer_run]) - -# Create a ContextType, e.g., Experiment with a note property -experiment_type = metadata_store_pb2.ContextType() -experiment_type.name = "Experiment" -experiment_type.properties["note"] = metadata_store_pb2.STRING -experiment_type_id = store.PutContextType(experiment_type) - -# Group the model and the trainer run to an experiment. -my_experiment = metadata_store_pb2.Context() -my_experiment.type_id = experiment_type_id -# Give the experiment a name -my_experiment.name = "exp1" -my_experiment.properties["note"].string_value = "My first experiment." -[experiment_id] = store.PutContexts([my_experiment]) - -attribution = metadata_store_pb2.Attribution() -attribution.artifact_id = model_artifact_id -attribution.context_id = experiment_id - -association = metadata_store_pb2.Association() -association.execution_id = run_id -association.context_id = experiment_id - -store.PutAttributionsAndAssociations([attribution], [association]) - -# Query the Artifacts and Executions that are linked to the Context. -experiment_artifacts = store.GetArtifactsByContext(experiment_id) -experiment_executions = store.GetExecutionsByContext(experiment_id) - -# You can also use neighborhood queries to fetch these artifacts and executions -# with conditions. -experiment_artifacts_with_conditions = store.GetArtifacts( - list_options = mlmd.ListOptions( - filter_query=('contexts_a.type = "Experiment" AND contexts_a.name = "exp1"'))) -experiment_executions_with_conditions = store.GetExecutions( - list_options = mlmd.ListOptions( - filter_query=('contexts_a.id = {}'.format(experiment_id)))) - - +def main(): + # connection_config = metadata_store_pb2.ConnectionConfig() + # connection_config.sqlite.filename_uri = './metadata.sqlite' + # connection_config.sqlite.connection_mode = 3 # READWRITE_OPENCREATE + # store = metadata_store.MetadataStore(connection_config) + + # connection_config = metadata_store_pb2.ConnectionConfig() + # connection_config.mysql.host = 'localhost' + # connection_config.mysql.port = 3306 + # connection_config.mysql.database = 'mlmetadata' + # connection_config.mysql.user = 'root' + # connection_config.mysql.password = 'my-secret-pw' + # store = metadata_store.MetadataStore(connection_config, enable_upgrade_migration=True) + + channel = insecure_channel('localhost:8080') + store = metadata_store_service_pb2_grpc.MetadataStoreServiceStub(channel) + + # Create ArtifactTypes, e.g., Data and Model + data_type = metadata_store_pb2.ArtifactType() + data_type.name = "DataSet" + data_type.properties["day"] = metadata_store_pb2.INT + data_type.properties["split"] = metadata_store_pb2.STRING + data_type_id = store.PutArtifactType(data_type) + + model_type = metadata_store_pb2.ArtifactType() + model_type.name = "SavedModel" + model_type.properties["version"] = metadata_store_pb2.INT + model_type.properties["name"] = metadata_store_pb2.STRING + model_type_id = store.PutArtifactType(model_type) + + # Query all registered Artifact types. + artifact_types = store.GetArtifactTypes() + + # Create an ExecutionType, e.g., Trainer + trainer_type = metadata_store_pb2.ExecutionType() + trainer_type.name = "Trainer" + trainer_type.properties["state"] = metadata_store_pb2.STRING + trainer_type_id = store.PutExecutionType(trainer_type) + + # Query a registered Execution type with the returned id + [registered_type] = store.GetExecutionTypesByID([trainer_type_id]) + + # Create an input artifact of type DataSet + data_artifact = metadata_store_pb2.Artifact() + data_artifact.uri = 'path/to/data' + data_artifact.properties["day"].int_value = 1 + data_artifact.properties["split"].string_value = 'train' + data_artifact.type_id = data_type_id + [data_artifact_id] = store.PutArtifacts([data_artifact]) + + # Query all registered Artifacts + artifacts = store.GetArtifacts() + + # Plus, there are many ways to query the same Artifact + [stored_data_artifact] = store.GetArtifactsByID([data_artifact_id]) + artifacts_with_uri = store.GetArtifactsByURI(data_artifact.uri) + artifacts_with_conditions = store.GetArtifacts( + list_options=mlmd.ListOptions( + filter_query='uri LIKE "%/data" AND properties.day.int_value > 0')) + + # Register the Execution of a Trainer run + trainer_run = metadata_store_pb2.Execution() + trainer_run.type_id = trainer_type_id + trainer_run.properties["state"].string_value = "RUNNING" + [run_id] = store.PutExecutions([trainer_run]) + + # Query all registered Execution + executions = store.GetExecutionsByID([run_id]) + # Similarly, the same execution can be queried with conditions. + executions_with_conditions = store.GetExecutions( + list_options = mlmd.ListOptions( + filter_query='type = "Trainer" AND properties.state.string_value IS NOT NULL')) + + # Define the input event + input_event = metadata_store_pb2.Event() + input_event.artifact_id = data_artifact_id + input_event.execution_id = run_id + input_event.type = metadata_store_pb2.Event.DECLARED_INPUT + + # Record the input event in the metadata store + store.put_events([input_event]) + + # Declare the output artifact of type SavedModel + model_artifact = metadata_store_pb2.Artifact() + model_artifact.uri = 'path/to/model/file' + model_artifact.properties["version"].int_value = 1 + model_artifact.properties["name"].string_value = 'MNIST-v1' + model_artifact.type_id = model_type_id + [model_artifact_id] = store.PutArtifacts([model_artifact]) + + # Declare the output event + output_event = metadata_store_pb2.Event() + output_event.artifact_id = model_artifact_id + output_event.execution_id = run_id + output_event.type = metadata_store_pb2.Event.DECLARED_OUTPUT + + # Submit output event to the Metadata Store + store.PutEvents([output_event]) + + trainer_run.id = run_id + trainer_run.properties["state"].string_value = "COMPLETED" + store.PutExecutions([trainer_run]) + + # Create a ContextType, e.g., Experiment with a note property + experiment_type = metadata_store_pb2.ContextType() + experiment_type.name = "Experiment" + experiment_type.properties["note"] = metadata_store_pb2.STRING + experiment_type_id = store.PutContextType(experiment_type) + + # Group the model and the trainer run to an experiment. + my_experiment = metadata_store_pb2.Context() + my_experiment.type_id = experiment_type_id + # Give the experiment a name + my_experiment.name = "exp1" + my_experiment.properties["note"].string_value = "My first experiment." + [experiment_id] = store.PutContexts([my_experiment]) + + attribution = metadata_store_pb2.Attribution() + attribution.artifact_id = model_artifact_id + attribution.context_id = experiment_id + + association = metadata_store_pb2.Association() + association.execution_id = run_id + association.context_id = experiment_id + + store.PutAttributionsAndAssociations([attribution], [association]) + + # Query the Artifacts and Executions that are linked to the Context. + experiment_artifacts = store.GetArtifactsByContext(experiment_id) + experiment_executions = store.GetExecutionsByContext(experiment_id) + + # You can also use neighborhood queries to fetch these artifacts and executions + # with conditions. + experiment_artifacts_with_conditions = store.GetArtifacts( + list_options = mlmd.ListOptions( + filter_query=('contexts_a.type = "Experiment" AND contexts_a.name = "exp1"'))) + experiment_executions_with_conditions = store.GetExecutions( + list_options = mlmd.ListOptions( + filter_query=('contexts_a.id = {}'.format(experiment_id)))) + +if __name__ == '__main__': + main() From 9920796cfe9f43040a215881ec8e47fea2137df9 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 31 Aug 2023 13:15:56 -0700 Subject: [PATCH 007/254] Add glog flags --- Makefile | 2 +- cmd/root.go | 10 +++++++--- cmd/serve.go | 45 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index a3b61345..45ec0ac3 100644 --- a/Makefile +++ b/Makefile @@ -19,4 +19,4 @@ run/client: gen/grpc python3.9 test/python/test_mlmetadata.py serve: build - ./ml-metadata-go-server serve + ./ml-metadata-go-server serve --logtostderr=true diff --git a/cmd/root.go b/cmd/root.go index c21b05ad..f6b9a80f 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -16,8 +16,9 @@ limitations under the License. package cmd import ( + "flag" "fmt" - "log" + "github.com/golang/glog" "os" "github.com/spf13/cobra" @@ -45,9 +46,9 @@ to quickly create a Cobra application.`, // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { err := rootCmd.Execute() + glog.Flush() if err != nil { - log.Fatalf("error: %v", err) - os.Exit(1) + glog.Exitf("error: %v", err) } } @@ -59,10 +60,13 @@ func init() { // will be global for your application. rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ml-metadata-go-server.yaml)") + // also add standard glog flags + rootCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) // Cobra also supports local flags, which will only run // when this action is called directly. rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + } // initConfig reads in config file and ENV variables if set. diff --git a/cmd/serve.go b/cmd/serve.go index a73312c2..079c13a4 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -30,7 +30,8 @@ import ( "log" "net" "os" - "sync" + "os/signal" + "syscall" ) func InterceptorLogger(l *log.Logger) logging.Logger { @@ -67,7 +68,13 @@ Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.`, RunE: func(cmd *cobra.Command, args []string) error { - fmt.Println("serve called") + glog.Info("server started...") + + // Create a channel to receive signals + signalChannel := make(chan os.Signal, 1) + + // Notify the channel on SIGINT (Ctrl+C) and SIGTERM signals + signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) // connect to the DB using Gorm db, err := NewDatabaseConnection(dbFile) @@ -99,22 +106,44 @@ to quickly create a Cobra application.`, proto.RegisterMetadataStoreServiceServer(grpcServer, server.NewGrpcServer(db)) reflection.Register(grpcServer) - var wg sync.WaitGroup - wg.Add(1) go func() { glog.Info("Starting grpc server...") err = grpcServer.Serve(listen) if err != nil { - log.Fatalf("grpc serving failed: %v", err) + glog.Errorf("grpc serving failed: %v", err) + signalChannel <- syscall.SIGTERM } - wg.Done() }() // TODO serve the GraphQL server - // wait for servers to finish - wg.Wait() + // error starting server + if err != nil { + return err + } + + // Wait for a signal + receivedSignal := <-signalChannel + glog.Infof("received signal: %s\n", receivedSignal) + + // Perform cleanup or other graceful shutdown actions here + glog.Info("shutting down services...") + // stop grpc server + grpcServer.Stop() + // TODO stop graphql server + + // close DB + glog.Info("closing DB...") + sqlDB, err := db.DB() + if err != nil { + return fmt.Errorf("error accessing DB: %v", err) + } + err = sqlDB.Close() + if err != nil { + return fmt.Errorf("error closing DB: %v", err) + } + glog.Info("shutdown!") return nil }, } From a2b71fcba4ff854d353ee521fc743a507afbe7fc Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 31 Aug 2023 15:45:41 -0700 Subject: [PATCH 008/254] Fixed simple PutArtifactType test --- model/db/typeproperty.gen.go | 2 +- server/grpc_server.go | 19 ++- test/python/test_mlmetadata.py | 231 +++++++++++++++++---------------- 3 files changed, 138 insertions(+), 114 deletions(-) diff --git a/model/db/typeproperty.gen.go b/model/db/typeproperty.gen.go index 43d36cec..98f32913 100644 --- a/model/db/typeproperty.gen.go +++ b/model/db/typeproperty.gen.go @@ -9,7 +9,7 @@ const TableNameTypeProperty = "TypeProperty" // TypeProperty mapped from table type TypeProperty struct { TypeID int32 `gorm:"column:type_id;primaryKey" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` + Name string `gorm:"column:name;primaryKey;not null" json:"-"` DataType *int32 `gorm:"column:data_type" json:"-"` } diff --git a/server/grpc_server.go b/server/grpc_server.go index c278d80e..1f57a274 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -6,6 +6,8 @@ import ( "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" "github.com/dhirajsb/ml-metadata-go-server/model/db" "github.com/golang/glog" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "gorm.io/gorm" ) @@ -78,15 +80,17 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif }, nil } -func (g grpcServer) createProperties(ctx context.Context, properties map[string]proto.PropertyType, value *db.Type) error { +func (g grpcServer) createProperties(ctx context.Context, properties map[string]proto.PropertyType, value *db.Type) (err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer closeDbConnection(ctx, &err) + for propName, prop := range properties { number := int32(prop.Number()) - property := db.TypeProperty{ + property := &db.TypeProperty{ TypeID: value.ID, Name: propName, DataType: &number, } - dbConn, _ := FromContext(ctx) if err := dbConn.Create(property).Error; err != nil { glog.Errorf("error creating type property %s: %v", propName, err) return err @@ -204,10 +208,19 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest } func closeDbConnection(ctx context.Context, err *error) { + // handle panic + if perr := recover(); perr != nil { + _ = Rollback(ctx) + *err = status.Errorf(codes.Internal, "server panic: %v", perr) + return + } if err == nil || *err == nil { *err = Commit(ctx) } else { _ = Rollback(ctx) + if _, ok := status.FromError(*err); !ok { + *err = status.Errorf(codes.Internal, "internal error: %v", *err) + } } } diff --git a/test/python/test_mlmetadata.py b/test/python/test_mlmetadata.py index 1779b3e3..c1ade54d 100644 --- a/test/python/test_mlmetadata.py +++ b/test/python/test_mlmetadata.py @@ -1,7 +1,10 @@ +import grpc import ml_metadata as mlmd +import ml_metadata.metadata_store.pywrap.metadata_store_extension.metadata_store from grpc import insecure_channel # from ml_metadata.metadata_store import metadata_store from ml_metadata.proto import metadata_store_pb2 +from ml_metadata.proto import metadata_store_service_pb2 from ml_metadata.proto import metadata_store_service_pb2_grpc def main(): @@ -26,123 +29,131 @@ def main(): data_type.name = "DataSet" data_type.properties["day"] = metadata_store_pb2.INT data_type.properties["split"] = metadata_store_pb2.STRING - data_type_id = store.PutArtifactType(data_type) + # data_type_id = store.PutArtifactType(data_type) + + request = metadata_store_service_pb2.PutArtifactTypeRequest() + request.all_fields_match = True + request.artifact_type.CopyFrom(data_type) + response = store.PutArtifactType(request) + data_type_id = response.type_id model_type = metadata_store_pb2.ArtifactType() model_type.name = "SavedModel" model_type.properties["version"] = metadata_store_pb2.INT model_type.properties["name"] = metadata_store_pb2.STRING - model_type_id = store.PutArtifactType(model_type) - - # Query all registered Artifact types. - artifact_types = store.GetArtifactTypes() - - # Create an ExecutionType, e.g., Trainer - trainer_type = metadata_store_pb2.ExecutionType() - trainer_type.name = "Trainer" - trainer_type.properties["state"] = metadata_store_pb2.STRING - trainer_type_id = store.PutExecutionType(trainer_type) - - # Query a registered Execution type with the returned id - [registered_type] = store.GetExecutionTypesByID([trainer_type_id]) - - # Create an input artifact of type DataSet - data_artifact = metadata_store_pb2.Artifact() - data_artifact.uri = 'path/to/data' - data_artifact.properties["day"].int_value = 1 - data_artifact.properties["split"].string_value = 'train' - data_artifact.type_id = data_type_id - [data_artifact_id] = store.PutArtifacts([data_artifact]) - - # Query all registered Artifacts - artifacts = store.GetArtifacts() - - # Plus, there are many ways to query the same Artifact - [stored_data_artifact] = store.GetArtifactsByID([data_artifact_id]) - artifacts_with_uri = store.GetArtifactsByURI(data_artifact.uri) - artifacts_with_conditions = store.GetArtifacts( - list_options=mlmd.ListOptions( - filter_query='uri LIKE "%/data" AND properties.day.int_value > 0')) - - # Register the Execution of a Trainer run - trainer_run = metadata_store_pb2.Execution() - trainer_run.type_id = trainer_type_id - trainer_run.properties["state"].string_value = "RUNNING" - [run_id] = store.PutExecutions([trainer_run]) - - # Query all registered Execution - executions = store.GetExecutionsByID([run_id]) - # Similarly, the same execution can be queried with conditions. - executions_with_conditions = store.GetExecutions( - list_options = mlmd.ListOptions( - filter_query='type = "Trainer" AND properties.state.string_value IS NOT NULL')) - - # Define the input event - input_event = metadata_store_pb2.Event() - input_event.artifact_id = data_artifact_id - input_event.execution_id = run_id - input_event.type = metadata_store_pb2.Event.DECLARED_INPUT - # Record the input event in the metadata store - store.put_events([input_event]) + request.artifact_type.CopyFrom(model_type) + model_type_id = store.PutArtifactType(request) - # Declare the output artifact of type SavedModel - model_artifact = metadata_store_pb2.Artifact() - model_artifact.uri = 'path/to/model/file' - model_artifact.properties["version"].int_value = 1 - model_artifact.properties["name"].string_value = 'MNIST-v1' - model_artifact.type_id = model_type_id - [model_artifact_id] = store.PutArtifacts([model_artifact]) - - # Declare the output event - output_event = metadata_store_pb2.Event() - output_event.artifact_id = model_artifact_id - output_event.execution_id = run_id - output_event.type = metadata_store_pb2.Event.DECLARED_OUTPUT - - # Submit output event to the Metadata Store - store.PutEvents([output_event]) - - trainer_run.id = run_id - trainer_run.properties["state"].string_value = "COMPLETED" - store.PutExecutions([trainer_run]) - - # Create a ContextType, e.g., Experiment with a note property - experiment_type = metadata_store_pb2.ContextType() - experiment_type.name = "Experiment" - experiment_type.properties["note"] = metadata_store_pb2.STRING - experiment_type_id = store.PutContextType(experiment_type) - - # Group the model and the trainer run to an experiment. - my_experiment = metadata_store_pb2.Context() - my_experiment.type_id = experiment_type_id - # Give the experiment a name - my_experiment.name = "exp1" - my_experiment.properties["note"].string_value = "My first experiment." - [experiment_id] = store.PutContexts([my_experiment]) - - attribution = metadata_store_pb2.Attribution() - attribution.artifact_id = model_artifact_id - attribution.context_id = experiment_id - - association = metadata_store_pb2.Association() - association.execution_id = run_id - association.context_id = experiment_id - - store.PutAttributionsAndAssociations([attribution], [association]) - - # Query the Artifacts and Executions that are linked to the Context. - experiment_artifacts = store.GetArtifactsByContext(experiment_id) - experiment_executions = store.GetExecutionsByContext(experiment_id) - - # You can also use neighborhood queries to fetch these artifacts and executions - # with conditions. - experiment_artifacts_with_conditions = store.GetArtifacts( - list_options = mlmd.ListOptions( - filter_query=('contexts_a.type = "Experiment" AND contexts_a.name = "exp1"'))) - experiment_executions_with_conditions = store.GetExecutions( - list_options = mlmd.ListOptions( - filter_query=('contexts_a.id = {}'.format(experiment_id)))) + # Query all registered Artifact types. + # artifact_types = store.GetArtifactTypes() + # + # # Create an ExecutionType, e.g., Trainer + # trainer_type = metadata_store_pb2.ExecutionType() + # trainer_type.name = "Trainer" + # trainer_type.properties["state"] = metadata_store_pb2.STRING + # trainer_type_id = store.PutExecutionType(trainer_type) + # + # # Query a registered Execution type with the returned id + # [registered_type] = store.GetExecutionTypesByID([trainer_type_id]) + # + # # Create an input artifact of type DataSet + # data_artifact = metadata_store_pb2.Artifact() + # data_artifact.uri = 'path/to/data' + # data_artifact.properties["day"].int_value = 1 + # data_artifact.properties["split"].string_value = 'train' + # data_artifact.type_id = data_type_id + # [data_artifact_id] = store.PutArtifacts([data_artifact]) + # + # # Query all registered Artifacts + # artifacts = store.GetArtifacts() + # + # # Plus, there are many ways to query the same Artifact + # [stored_data_artifact] = store.GetArtifactsByID([data_artifact_id]) + # artifacts_with_uri = store.GetArtifactsByURI(data_artifact.uri) + # artifacts_with_conditions = store.GetArtifacts( + # list_options=mlmd.ListOptions( + # filter_query='uri LIKE "%/data" AND properties.day.int_value > 0')) + # + # # Register the Execution of a Trainer run + # trainer_run = metadata_store_pb2.Execution() + # trainer_run.type_id = trainer_type_id + # trainer_run.properties["state"].string_value = "RUNNING" + # [run_id] = store.PutExecutions([trainer_run]) + # + # # Query all registered Execution + # executions = store.GetExecutionsByID([run_id]) + # # Similarly, the same execution can be queried with conditions. + # executions_with_conditions = store.GetExecutions( + # list_options = mlmd.ListOptions( + # filter_query='type = "Trainer" AND properties.state.string_value IS NOT NULL')) + # + # # Define the input event + # input_event = metadata_store_pb2.Event() + # input_event.artifact_id = data_artifact_id + # input_event.execution_id = run_id + # input_event.type = metadata_store_pb2.Event.DECLARED_INPUT + # + # # Record the input event in the metadata store + # store.put_events([input_event]) + # + # # Declare the output artifact of type SavedModel + # model_artifact = metadata_store_pb2.Artifact() + # model_artifact.uri = 'path/to/model/file' + # model_artifact.properties["version"].int_value = 1 + # model_artifact.properties["name"].string_value = 'MNIST-v1' + # model_artifact.type_id = model_type_id + # [model_artifact_id] = store.PutArtifacts([model_artifact]) + # + # # Declare the output event + # output_event = metadata_store_pb2.Event() + # output_event.artifact_id = model_artifact_id + # output_event.execution_id = run_id + # output_event.type = metadata_store_pb2.Event.DECLARED_OUTPUT + # + # # Submit output event to the Metadata Store + # store.PutEvents([output_event]) + # + # trainer_run.id = run_id + # trainer_run.properties["state"].string_value = "COMPLETED" + # store.PutExecutions([trainer_run]) + # + # # Create a ContextType, e.g., Experiment with a note property + # experiment_type = metadata_store_pb2.ContextType() + # experiment_type.name = "Experiment" + # experiment_type.properties["note"] = metadata_store_pb2.STRING + # experiment_type_id = store.PutContextType(experiment_type) + # + # # Group the model and the trainer run to an experiment. + # my_experiment = metadata_store_pb2.Context() + # my_experiment.type_id = experiment_type_id + # # Give the experiment a name + # my_experiment.name = "exp1" + # my_experiment.properties["note"].string_value = "My first experiment." + # [experiment_id] = store.PutContexts([my_experiment]) + # + # attribution = metadata_store_pb2.Attribution() + # attribution.artifact_id = model_artifact_id + # attribution.context_id = experiment_id + # + # association = metadata_store_pb2.Association() + # association.execution_id = run_id + # association.context_id = experiment_id + # + # store.PutAttributionsAndAssociations([attribution], [association]) + # + # # Query the Artifacts and Executions that are linked to the Context. + # experiment_artifacts = store.GetArtifactsByContext(experiment_id) + # experiment_executions = store.GetExecutionsByContext(experiment_id) + # + # # You can also use neighborhood queries to fetch these artifacts and executions + # # with conditions. + # experiment_artifacts_with_conditions = store.GetArtifacts( + # list_options = mlmd.ListOptions( + # filter_query=('contexts_a.type = "Experiment" AND contexts_a.name = "exp1"'))) + # experiment_executions_with_conditions = store.GetExecutions( + # list_options = mlmd.ListOptions( + # filter_query=('contexts_a.id = {}'.format(experiment_id)))) if __name__ == '__main__': main() From 2d32716d641f35ce58f7fe805f2737a74dafa8df Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 31 Aug 2023 19:30:34 -0700 Subject: [PATCH 009/254] Fixed artifact and property insert --- model/db/artifactproperty.gen.go | 14 +- server/grpc_server.go | 261 ++++++++++++++++++++++--------- test/python/test_mlmetadata.py | 61 +++++--- 3 files changed, 227 insertions(+), 109 deletions(-) diff --git a/model/db/artifactproperty.gen.go b/model/db/artifactproperty.gen.go index 6c962d79..9400dac2 100644 --- a/model/db/artifactproperty.gen.go +++ b/model/db/artifactproperty.gen.go @@ -9,14 +9,14 @@ const TableNameArtifactProperty = "ArtifactProperty" // ArtifactProperty mapped from table type ArtifactProperty struct { ArtifactID int32 `gorm:"column:artifact_id;primaryKey" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` + Name string `gorm:"column:name;primaryKey" json:"-"` IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` - IntValue int32 `gorm:"column:int_value;not null" json:"-"` - DoubleValue float64 `gorm:"column:double_value;not null" json:"-"` - StringValue string `gorm:"column:string_value;not null" json:"-"` - ByteValue []byte `gorm:"column:byte_value;not null" json:"-"` - ProtoValue []byte `gorm:"column:proto_value;not null" json:"-"` - BoolValue bool `gorm:"column:bool_value;not null" json:"-"` + IntValue *int32 `gorm:"column:int_value" json:"-"` + DoubleValue *float64 `gorm:"column:double_value" json:"-"` + StringValue *string `gorm:"column:string_value" json:"-"` + ByteValue []byte `gorm:"column:byte_value" json:"-"` + ProtoValue []byte `gorm:"column:proto_value" json:"-"` + BoolValue *bool `gorm:"column:bool_value" json:"-"` } // TableName ArtifactProperty's table name diff --git a/server/grpc_server.go b/server/grpc_server.go index 1f57a274..e51eff4a 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -2,10 +2,9 @@ package server import ( "context" - "errors" + "fmt" "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" "github.com/dhirajsb/ml-metadata-go-server/model/db" - "github.com/golang/glog" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" @@ -44,33 +43,30 @@ func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { return &grpcServer{dbConnection: dbConnection} } +var REQUIRED_TYPE_FIELDS = []string{"name"} + func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { ctx, dbConn := Begin(ctx, g.dbConnection) - defer closeDbConnection(ctx, &err) + defer handleTransaction(ctx, &err) artifactType := request.GetArtifactType() - name := artifactType.Name - if name == nil { - return nil, errors.New("missing required field name") + err = requiredFields(REQUIRED_TYPE_FIELDS, artifactType.Name) + if err != nil { + return nil, err } value := &db.Type{ - Name: *name, + Name: *artifactType.Name, TypeKind: int32(ARTIFACT_TYPE), } - if artifactType.Version != nil { - value.Version = *artifactType.Version - } - if artifactType.Description != nil { - value.Description = *artifactType.Description - } - if artifactType.ExternalId != nil { - value.ExternalID = *artifactType.ExternalId - } - if err := dbConn.Create(value).Error; err != nil { - glog.Errorf("error creating artifact type %s: %v", name, err) + nilSafeCopy(&value.Version, artifactType.Version, strToStr) + nilSafeCopy(&value.Description, artifactType.Description, strToStr) + nilSafeCopy(&value.ExternalID, artifactType.ExternalId, strToStr) + + if err = dbConn.Create(value).Error; err != nil { + err = fmt.Errorf("error creating artifact type %s: %v", value.Name, err) return nil, err } - err = g.createProperties(ctx, request.ArtifactType.Properties, value) + err = g.createTypeProperties(ctx, request.ArtifactType.Properties, value) if err != nil { return nil, err } @@ -80,44 +76,27 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif }, nil } -func (g grpcServer) createProperties(ctx context.Context, properties map[string]proto.PropertyType, value *db.Type) (err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) - defer closeDbConnection(ctx, &err) - - for propName, prop := range properties { - number := int32(prop.Number()) - property := &db.TypeProperty{ - TypeID: value.ID, - Name: propName, - DataType: &number, - } - if err := dbConn.Create(property).Error; err != nil { - glog.Errorf("error creating type property %s: %v", propName, err) - return err - } - } - return nil -} - func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { ctx, dbConn := Begin(ctx, g.dbConnection) - defer closeDbConnection(ctx, &err) + defer handleTransaction(ctx, &err) executionType := request.GetExecutionType() + err = requiredFields(REQUIRED_TYPE_FIELDS, executionType.Name) + if err != nil { + return nil, err + } value := &db.Type{ - Name: *executionType.Name, - Version: *executionType.Version, - TypeKind: int32(EXECUTION_TYPE), - Description: *(executionType.Description), - InputType: executionType.InputType.String(), - OutputType: executionType.OutputType.String(), - ExternalID: *(executionType.ExternalId), + Name: *executionType.Name, + TypeKind: int32(EXECUTION_TYPE), } + nilSafeCopy(&value.Version, executionType.Version, strToStr) + nilSafeCopy(&value.Description, executionType.Description, strToStr) + nilSafeCopy(&value.ExternalID, executionType.ExternalId, strToStr) if err = dbConn.Create(value).Error; err != nil { - glog.Errorf("error creating execution type %s: %v", executionType.Name, err) + err = fmt.Errorf("error creating execution type %s: %v", value.Name, err) return nil, err } - err = g.createProperties(ctx, request.ExecutionType.Properties, value) + err = g.createTypeProperties(ctx, request.ExecutionType.Properties, value) if err != nil { return nil, err } @@ -129,21 +108,25 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { ctx, dbConn := Begin(ctx, g.dbConnection) - defer closeDbConnection(ctx, &err) + defer handleTransaction(ctx, &err) - contextType := request.ContextType + contextType := request.GetContextType() + err = requiredFields(REQUIRED_TYPE_FIELDS, contextType.Name) + if err != nil { + return nil, err + } value := &db.Type{ - Name: *contextType.Name, - Version: *contextType.Version, - TypeKind: int32(CONTEXT_TYPE), - Description: *(contextType.Description), - ExternalID: *(contextType.ExternalId), + Name: *contextType.Name, + TypeKind: int32(CONTEXT_TYPE), } - if err := dbConn.Create(value).Error; err != nil { - glog.Errorf("error creating type %s: %v", contextType.Name, err) + nilSafeCopy(&value.Version, contextType.Version, strToStr) + nilSafeCopy(&value.Description, contextType.Description, strToStr) + nilSafeCopy(&value.ExternalID, contextType.ExternalId, strToStr) + if err = dbConn.Create(value).Error; err != nil { + err = fmt.Errorf("error creating context type %s: %v", value.Name, err) return nil, err } - err = g.createProperties(ctx, request.ContextType.Properties, value) + err = g.createTypeProperties(ctx, request.ContextType.Properties, value) if err != nil { return nil, err } @@ -155,7 +138,7 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest) (resp *proto.PutTypesResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) - defer closeDbConnection(ctx, &err) + defer handleTransaction(ctx, &err) response := &proto.PutTypesResponse{} @@ -207,26 +190,46 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest return response, nil } -func closeDbConnection(ctx context.Context, err *error) { - // handle panic - if perr := recover(); perr != nil { - _ = Rollback(ctx) - *err = status.Errorf(codes.Internal, "server panic: %v", perr) - return - } - if err == nil || *err == nil { - *err = Commit(ctx) - } else { - _ = Rollback(ctx) - if _, ok := status.FromError(*err); !ok { - *err = status.Errorf(codes.Internal, "internal error: %v", *err) +var REQUIRED_ARTIFACT_FIELDS = []string{"type_id", "uri"} + +func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (resp *proto.PutArtifactsResponse, err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer handleTransaction(ctx, &err) + + var artifactIds []int64 + for _, artifact := range request.Artifacts { + err = requiredFields(REQUIRED_ARTIFACT_FIELDS, artifact.TypeId, artifact.Uri) + if err != nil { + return nil, err + } + value := &db.Artifact{ + TypeID: int32(*artifact.TypeId), + URI: *artifact.Uri, + } + nilSafeCopy(&value.ID, artifact.Id, int64ToInt32) + nilSafeCopy(&value.State, artifact.State, artifactStateToInt32) + nilSafeCopy(&value.Name, artifact.Name, strToStr) + nilSafeCopy(&value.ExternalID, artifact.ExternalId, strToStr) + // create in DB + if err = dbConn.Create(value).Error; err != nil { + err = fmt.Errorf("error creating artifact with type_id[%d], name[%s]: %w", value.TypeID, value.Name, err) + return nil, err + } + // create properties in DB + err = g.createArtifactProperties(ctx, value.ID, artifact.GetProperties(), false) + if err != nil { + return nil, err } + err = g.createArtifactProperties(ctx, value.ID, artifact.GetCustomProperties(), true) + if err != nil { + return nil, err + } + artifactIds = append(artifactIds, int64(value.ID)) } -} - -func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (*proto.PutArtifactsResponse, error) { - //TODO implement me - panic("implement me") + resp = &proto.PutArtifactsResponse{ + ArtifactIds: artifactIds, + } + return resp, nil } func (g grpcServer) PutExecutions(ctx context.Context, request *proto.PutExecutionsRequest) (*proto.PutExecutionsResponse, error) { @@ -468,3 +471,107 @@ func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { //TODO implement me panic("implement me") } + +func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, value *db.Type) (err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer handleTransaction(ctx, &err) + + for propName, prop := range properties { + number := int32(prop.Number()) + property := &db.TypeProperty{ + TypeID: value.ID, + Name: propName, + DataType: &number, + } + if err = dbConn.Create(property).Error; err != nil { + err = fmt.Errorf("error creating type property for type_id[%d] with name[%s]: %v", value.ID, propName, err) + return err + } + } + return nil +} + +func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int32, properties map[string]*proto.Value, isCustomProperty bool) (err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer handleTransaction(ctx, &err) + + for propName, prop := range properties { + property := &db.ArtifactProperty{ + ArtifactID: artifactId, + Name: propName, + } + if isCustomProperty { + property.IsCustomProperty = 1 + } + // TODO handle polymorphic value with null columns + intValue, ok := prop.GetValue().(*proto.Value_IntValue) + if ok { + i := int32(intValue.IntValue) + property.IntValue = &i + } + doubleValue, ok := prop.GetValue().(*proto.Value_DoubleValue) + if ok { + property.DoubleValue = &doubleValue.DoubleValue + } + stringValue, ok := prop.GetValue().(*proto.Value_StringValue) + if ok { + property.StringValue = &stringValue.StringValue + } + structValue, ok := prop.GetValue().(*proto.Value_StructValue) + if ok { + property.ByteValue = []byte(fmt.Sprintf("%s", structValue.StructValue)) + } + protoValue, ok := prop.GetValue().(*proto.Value_ProtoValue) + if ok { + property.ProtoValue = []byte(fmt.Sprintf("%s", protoValue.ProtoValue)) + } + boolValue, ok := prop.GetValue().(*proto.Value_BoolValue) + if ok { + property.BoolValue = &boolValue.BoolValue + } + if err = dbConn.Create(property).Error; err != nil { + err = fmt.Errorf("error creating artifact property for type_id[%d] with name %s: %v", artifactId, propName, err) + return err + } + } + return nil +} + +func int64ToInt32(i int64) int32 { return int32(i) } +func artifactStateToInt32(i proto.Artifact_State) int32 { return int32(i) } +func strToStr(i string) string { return i } + +func requiredFields(names []string, args ...interface{}) error { + var missing []string + for i, a := range args { + if a == nil { + missing = append(missing, names[i]) + } + } + if len(missing) > 0 { + return fmt.Errorf("missing required properties: %s", missing) + } + return nil +} + +func nilSafeCopy[D int32 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { + if src != nil { + *dest = f(*src) + } +} +func handleTransaction(ctx context.Context, err *error) { + // handle panic + if perr := recover(); perr != nil { + _ = Rollback(ctx) + *err = status.Errorf(codes.Internal, "server panic: %v", perr) + return + } + if err == nil || *err == nil { + *err = Commit(ctx) + } else { + _ = Rollback(ctx) + if _, ok := status.FromError(*err); !ok { + *err = status.Errorf(codes.Internal, "internal error: %v", *err) + } + } +} diff --git a/test/python/test_mlmetadata.py b/test/python/test_mlmetadata.py index c1ade54d..aa018b3c 100644 --- a/test/python/test_mlmetadata.py +++ b/test/python/test_mlmetadata.py @@ -29,7 +29,6 @@ def main(): data_type.name = "DataSet" data_type.properties["day"] = metadata_store_pb2.INT data_type.properties["split"] = metadata_store_pb2.STRING - # data_type_id = store.PutArtifactType(data_type) request = metadata_store_service_pb2.PutArtifactTypeRequest() request.all_fields_match = True @@ -43,28 +42,37 @@ def main(): model_type.properties["name"] = metadata_store_pb2.STRING request.artifact_type.CopyFrom(model_type) - model_type_id = store.PutArtifactType(request) + response = store.PutArtifactType(request) + model_type_id = response.type_id # Query all registered Artifact types. # artifact_types = store.GetArtifactTypes() - # - # # Create an ExecutionType, e.g., Trainer - # trainer_type = metadata_store_pb2.ExecutionType() - # trainer_type.name = "Trainer" - # trainer_type.properties["state"] = metadata_store_pb2.STRING - # trainer_type_id = store.PutExecutionType(trainer_type) - # + + # Create an ExecutionType, e.g., Trainer + trainer_type = metadata_store_pb2.ExecutionType() + trainer_type.name = "Trainer" + trainer_type.properties["state"] = metadata_store_pb2.STRING + + request = metadata_store_service_pb2.PutExecutionTypeRequest() + request.execution_type.CopyFrom(trainer_type) + response = store.PutExecutionType(request) + trainer_type_id = response.type_id + # # Query a registered Execution type with the returned id # [registered_type] = store.GetExecutionTypesByID([trainer_type_id]) - # - # # Create an input artifact of type DataSet - # data_artifact = metadata_store_pb2.Artifact() - # data_artifact.uri = 'path/to/data' - # data_artifact.properties["day"].int_value = 1 - # data_artifact.properties["split"].string_value = 'train' - # data_artifact.type_id = data_type_id - # [data_artifact_id] = store.PutArtifacts([data_artifact]) - # + + # Create an input artifact of type DataSet + data_artifact = metadata_store_pb2.Artifact() + data_artifact.uri = 'path/to/data' + data_artifact.properties["day"].int_value = 1 + data_artifact.properties["split"].string_value = 'train' + data_artifact.type_id = data_type_id + + request = metadata_store_service_pb2.PutArtifactsRequest() + request.artifacts.extend([data_artifact]) + response = store.PutArtifacts(request) + data_artifact_id = response.artifact_ids[0] + # # Query all registered Artifacts # artifacts = store.GetArtifacts() # @@ -117,13 +125,16 @@ def main(): # trainer_run.id = run_id # trainer_run.properties["state"].string_value = "COMPLETED" # store.PutExecutions([trainer_run]) - # - # # Create a ContextType, e.g., Experiment with a note property - # experiment_type = metadata_store_pb2.ContextType() - # experiment_type.name = "Experiment" - # experiment_type.properties["note"] = metadata_store_pb2.STRING - # experiment_type_id = store.PutContextType(experiment_type) - # + + # Create a ContextType, e.g., Experiment with a note property + experiment_type = metadata_store_pb2.ContextType() + experiment_type.name = "Experiment" + experiment_type.properties["note"] = metadata_store_pb2.STRING + request = metadata_store_service_pb2.PutContextTypeRequest() + request.context_type.CopyFrom(experiment_type) + response = store.PutContextType(request) + experiment_type_id = response.type_id + # # Group the model and the trainer run to an experiment. # my_experiment = metadata_store_pb2.Context() # my_experiment.type_id = experiment_type_id From c829f17df3bd71b09109c27e5f4896efcb406f4d Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 31 Aug 2023 23:19:55 -0700 Subject: [PATCH 010/254] Added support for loading metadata libraries --- Makefile | 4 +- cmd/migrate.go | 105 ++++++++++++++++-- cmd/root.go | 1 - .../metadata-library/ml-metadata-library.yaml | 12 ++ main.go | 7 +- server/library/metadata_library.go | 34 ++++++ 6 files changed, 152 insertions(+), 11 deletions(-) create mode 100644 config/metadata-library/ml-metadata-library.yaml create mode 100644 server/library/metadata_library.go diff --git a/Makefile b/Makefile index 45ec0ac3..ce4a4eda 100644 --- a/Makefile +++ b/Makefile @@ -10,10 +10,10 @@ build: gen/grpc go build run/migrate: gen/grpc - go run main.go migrate + go run main.go migrate --logtostderr=true run/server: gen/grpc - go run main.go serve + go run main.go serve --logtostderr=true run/client: gen/grpc python3.9 test/python/test_mlmetadata.py diff --git a/cmd/migrate.go b/cmd/migrate.go index 1f1102ec..40e6d1bc 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -16,10 +16,19 @@ limitations under the License. package cmd import ( + "context" "fmt" + "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" "github.com/dhirajsb/ml-metadata-go-server/model/db" + "github.com/dhirajsb/ml-metadata-go-server/server" + "github.com/dhirajsb/ml-metadata-go-server/server/library" "github.com/golang/glog" "github.com/spf13/cobra" + yaml "gopkg.in/yaml.v3" + "io/fs" + "os" + "path/filepath" + "strings" ) // migrateCmd represents the migrate command @@ -35,12 +44,21 @@ to quickly create a Cobra application.`, RunE: func(cmd *cobra.Command, args []string) error { // connect to DB dbConn, err := NewDatabaseConnection(dbFile) + defer func() { + // close DB connection on exit + db, err2 := dbConn.DB() + if err2 != nil { + err2 = db.Close() + if err2 != nil { + glog.Warningf("error closing DB connection: %v", err2) + } + } + }() if err != nil { - err = fmt.Errorf("db connection failed: %w", err) - glog.Error(err) - return err + return fmt.Errorf("db connection failed: %w", err) } // migrate all DB types + // TODO add support for more elaborate Gorm migrations err = dbConn.AutoMigrate( db.Artifact{}, db.ArtifactProperty{}, @@ -58,14 +76,86 @@ to quickly create a Cobra application.`, db.TypeProperty{}, ) if err != nil { - err = fmt.Errorf("db migration failed: %w", err) - glog.Error(err) - return err + return fmt.Errorf("db migration failed: %w", err) + } + + // load metadata type libraries + for _, dir := range libraryDirs { + abs, err := filepath.Abs(dir) + if err != nil { + return fmt.Errorf("error getting absolute library path for %s: %w", dir, err) + } + _, err = os.Stat(abs) + if err != nil { + return fmt.Errorf("error opening library path for %s: %w", abs, err) + } + err = filepath.WalkDir(abs, func(path string, entry fs.DirEntry, err error) error { + if err != nil { + glog.Warningf("error reading library path %s: %v", path, err) + return filepath.SkipDir + } + if entry.IsDir() || !isYamlFile(path) { + return nil + } + + bytes, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read library file %s: %w", path, err) + } + var lib library.MetadataLibrary + err = yaml.Unmarshal(bytes, &lib) + grpcServer := server.NewGrpcServer(dbConn) + typesRequest := proto.PutTypesRequest{} + for _, ar := range lib.ArtifactTypes { + typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ + Name: ar.Name, + Version: ar.Version, + Description: ar.Description, + ExternalId: ar.ExternalId, + Properties: ar.Properties, + }) + } + for _, ar := range lib.ContextTypes { + typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ + Name: ar.Name, + Version: ar.Version, + Description: ar.Description, + ExternalId: ar.ExternalId, + Properties: ar.Properties, + }) + } + for _, ar := range lib.ExecutionTypes { + typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ + Name: ar.Name, + Version: ar.Version, + Description: ar.Description, + ExternalId: ar.ExternalId, + Properties: ar.Properties, + }) + } + response, err := grpcServer.PutTypes(context.Background(), &typesRequest) + if err != nil { + return fmt.Errorf("failed to add library from file %s: %w", path, err) + } + glog.Infof("added %d artifacts, %d contexts and %d execution types from library file %s", + len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) + return nil + }) + if err != nil { + return fmt.Errorf("failed to read library directory %s: %w", abs, err) + } } return nil }, } +func isYamlFile(path string) bool { + lowerPath := strings.ToLower(filepath.Ext(path)) + return strings.HasSuffix(lowerPath, ".yaml") || strings.HasSuffix(lowerPath, ".yml") +} + +var libraryDirs []string + func init() { rootCmd.AddCommand(migrateCmd) @@ -77,5 +167,6 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: - migrateCmd.Flags().StringVar(&dbFile, "db-file", "metadata.sqlite.db", "Sqlite DB file") + migrateCmd.Flags().StringVarP(&dbFile, "db-file", "d", "metadata.sqlite.db", "Sqlite DB file") + migrateCmd.Flags().StringSliceVarP(&libraryDirs, "metadata-library-dir", "m", libraryDirs, "Built-in metadata types library directories containing yaml files") } diff --git a/cmd/root.go b/cmd/root.go index f6b9a80f..753cb2f4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -46,7 +46,6 @@ to quickly create a Cobra application.`, // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { err := rootCmd.Execute() - glog.Flush() if err != nil { glog.Exitf("error: %v", err) } diff --git a/config/metadata-library/ml-metadata-library.yaml b/config/metadata-library/ml-metadata-library.yaml new file mode 100644 index 00000000..bf694128 --- /dev/null +++ b/config/metadata-library/ml-metadata-library.yaml @@ -0,0 +1,12 @@ +# types for ml-metadata library +artifact-types: + - name: "mlmd.Dataset" + - name: "mlmd.Model" + - name: "mlmd.Metrics" + - name: "mlmd.Statistics" +execution-types: + - name: "mlmd.Train" + - name: "mlmd.Transform" + - name: "mlmd.Process" + - name: "mlmd.Evaluate" + - name: "mlmd.Deploy" diff --git a/main.go b/main.go index c1f1a032..65adbebc 100644 --- a/main.go +++ b/main.go @@ -15,8 +15,13 @@ limitations under the License. */ package main -import "github.com/dhirajsb/ml-metadata-go-server/cmd" +import ( + "github.com/dhirajsb/ml-metadata-go-server/cmd" + "github.com/golang/glog" +) func main() { + defer glog.Flush() + cmd.Execute() } diff --git a/server/library/metadata_library.go b/server/library/metadata_library.go new file mode 100644 index 00000000..ad0fd7a3 --- /dev/null +++ b/server/library/metadata_library.go @@ -0,0 +1,34 @@ +package library + +import "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" + +type MetadataType struct { + Name *string `yaml:"name,omitempty"` + Version *string `yaml:"version,omitempty"` + Description *string `yaml:"description,omitempty"` + ExternalId *string `yaml:"external_id,omitempty"` + Properties map[string]proto.PropertyType `yaml:"properties,omitempty"` +} + +type ArtifactType struct { + MetadataType `yaml:",inline"` + // TODO add support for base type enum + //BaseType *ArtifactType_SystemDefinedBaseType `yaml:"base_type,omitempty"` +} + +type ContextType struct { + MetadataType `yaml:",inline"` +} + +type ExecutionType struct { + MetadataType `yaml:",inline"` + //InputType *ArtifactStructType `yaml:"input_type,omitempty"` + //OutputType *ArtifactStructType `yaml:"output_type,omitempty"` + //BaseType *ExecutionType_SystemDefinedBaseType `yaml:"base_type,omitempty"` +} + +type MetadataLibrary struct { + ArtifactTypes []ArtifactType `yaml:"artifact-types,omitempty"` + ContextTypes []ArtifactType `yaml:"context-types,omitempty"` + ExecutionTypes []ArtifactType `yaml:"execution-types,omitempty"` +} From 4f9845a764a7813e468806471923f82dc6ec5fe2 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 1 Sep 2023 08:02:07 -0700 Subject: [PATCH 011/254] Created api directory for grpc protos --- Makefile | 6 +++--- .../grpc/ml_metadata}/proto/metadata_source.proto | 0 .../grpc/ml_metadata}/proto/metadata_store.proto | 0 .../grpc/ml_metadata}/proto/metadata_store_service.proto | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename {ml_metadata => api/grpc/ml_metadata}/proto/metadata_source.proto (100%) rename {ml_metadata => api/grpc/ml_metadata}/proto/metadata_store.proto (100%) rename {ml_metadata => api/grpc/ml_metadata}/proto/metadata_store_service.proto (100%) diff --git a/Makefile b/Makefile index ce4a4eda..bf28c014 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ -gen/grpc: ml_metadata/proto/*.proto - protoc --go_out=. --go_opt=paths=source_relative \ +gen/grpc: api/grpc/ml_metadata/proto/*.proto + protoc -I./api/grpc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ ml_metadata/proto/metadata_store.proto ml_metadata/proto/metadata_store_service.proto clean: - rm -Rf ml_metadata/*.go + rm -Rf ml_metadata/proto/*.go build: gen/grpc go build diff --git a/ml_metadata/proto/metadata_source.proto b/api/grpc/ml_metadata/proto/metadata_source.proto similarity index 100% rename from ml_metadata/proto/metadata_source.proto rename to api/grpc/ml_metadata/proto/metadata_source.proto diff --git a/ml_metadata/proto/metadata_store.proto b/api/grpc/ml_metadata/proto/metadata_store.proto similarity index 100% rename from ml_metadata/proto/metadata_store.proto rename to api/grpc/ml_metadata/proto/metadata_store.proto diff --git a/ml_metadata/proto/metadata_store_service.proto b/api/grpc/ml_metadata/proto/metadata_store_service.proto similarity index 100% rename from ml_metadata/proto/metadata_store_service.proto rename to api/grpc/ml_metadata/proto/metadata_store_service.proto From d48651d4e3335127f8b2b5d17c55bca81c246ab6 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 1 Sep 2023 09:31:48 -0700 Subject: [PATCH 012/254] Fixed clean target --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bf28c014..2b48bd7c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ gen/grpc: api/grpc/ml_metadata/proto/*.proto ml_metadata/proto/metadata_store.proto ml_metadata/proto/metadata_store_service.proto clean: - rm -Rf ml_metadata/proto/*.go + rm -Rf ml_metadata/proto/*.go ./ml-metadata-go-server build: gen/grpc go build @@ -20,3 +20,5 @@ run/client: gen/grpc serve: build ./ml-metadata-go-server serve --logtostderr=true + +all: build From feb3b351ad9acd04cc4ac19181561a32fb800dd6 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 1 Sep 2023 09:32:30 -0700 Subject: [PATCH 013/254] Added short and long cmd descriptions --- cmd/migrate.go | 9 ++++----- cmd/root.go | 17 ++++++++++------- cmd/serve.go | 16 +++++++--------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/cmd/migrate.go b/cmd/migrate.go index 40e6d1bc..e6da78e1 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -35,12 +35,11 @@ import ( var migrateCmd = &cobra.Command{ Use: "migrate", Short: "Migrate ml-metadata DB to latest schema", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: + Long: `This command migrates an existing DB to the latest schema +used by ml-metadata-go-server. It can also create a new DB if it doesn't exist. -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, +This command can create a new ml-metadata Sqlite DB, or migrate an existing DB +to the latest schema required by this server.`, RunE: func(cmd *cobra.Command, args []string) error { // connect to DB dbConn, err := NewDatabaseConnection(dbFile) diff --git a/cmd/root.go b/cmd/root.go index 753cb2f4..e429c679 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -30,13 +30,16 @@ var cfgFile string // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ Use: "ml-metadata-go-server", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, + Short: "A go server for ml-metadata", + Long: `The ml-metadata-go-server is a gRPC server that stores metadata +for ML applications. + +It's based on the ml-metadata project that provides a python client library +for ML applications to record metadata about metadata such as Artifacts, +Executions and Contexts. +This go server is an alternative to the CPP gRPC service provided by the +ml-metadata project. It's meant to provide extra features such as loading +custom metadata libraries, exposing a higher level GraphQL API, RBAC, etc.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, diff --git a/cmd/serve.go b/cmd/serve.go index 079c13a4..56c9029d 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -60,13 +60,11 @@ var ( // serveCmd represents the serve command serveCmd = &cobra.Command{ Use: "serve", - Short: "A brief description of your command", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: + Short: "Starts the ml-metadata go server", + Long: `This command launches the ml-metadata go server. -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, +The server connects to a SQlite database. It supports options to customize the +location of the database file and the hostname and port where it listens.'`, RunE: func(cmd *cobra.Command, args []string) error { glog.Info("server started...") @@ -164,7 +162,7 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: - serveCmd.Flags().StringVar(&dbFile, "db-file", "metadata.sqlite.db", "Sqlite DB file") - serveCmd.Flags().StringVar(&grpcHost, "grpc-host", grpcHost, "gRPC listen hostname") - serveCmd.Flags().IntVar(&grpcPort, "grpc-port", grpcPort, "gRPC listen port") + serveCmd.Flags().StringVarP(&dbFile, "db-file", "d", "metadata.sqlite.db", "Sqlite DB file") + serveCmd.Flags().StringVarP(&grpcHost, "grpc-host", "h", grpcHost, "gRPC listen hostname") + serveCmd.Flags().IntVarP(&grpcPort, "grpc-port", "p", grpcPort, "gRPC listen port") } From 9c2bad406dd0becbbd04b90ca385ba4868e1feb5 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 1 Sep 2023 10:13:17 -0700 Subject: [PATCH 014/254] Fixed ID sizes in DB model --- model/db/artifact.gen.go | 4 ++-- model/db/artifactproperty.gen.go | 2 +- model/db/association.gen.go | 6 +++--- model/db/attribution.gen.go | 6 +++--- model/db/context.gen.go | 4 ++-- model/db/contextproperty.gen.go | 2 +- model/db/event.gen.go | 6 +++--- model/db/eventpath.gen.go | 2 +- model/db/execution.gen.go | 4 ++-- model/db/executionproperty.gen.go | 2 +- model/db/parentcontext.gen.go | 4 ++-- model/db/parenttype.gen.go | 4 ++-- model/db/type.gen.go | 2 +- model/db/typeproperty.gen.go | 2 +- server/grpc_server.go | 33 +++++++++++++++---------------- 15 files changed, 41 insertions(+), 42 deletions(-) diff --git a/model/db/artifact.gen.go b/model/db/artifact.gen.go index 711deaf4..ed3e41ab 100644 --- a/model/db/artifact.gen.go +++ b/model/db/artifact.gen.go @@ -8,8 +8,8 @@ const TableNameArtifact = "Artifact" // Artifact mapped from table type Artifact struct { - ID int32 `gorm:"column:id;primaryKey" json:"-"` - TypeID int32 `gorm:"column:type_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey" json:"-"` + TypeID int64 `gorm:"column:type_id;not null" json:"-"` URI string `gorm:"column:uri;not null" json:"-"` State int32 `gorm:"column:state;not null" json:"-"` Name string `gorm:"column:name;not null" json:"-"` diff --git a/model/db/artifactproperty.gen.go b/model/db/artifactproperty.gen.go index 9400dac2..8986042e 100644 --- a/model/db/artifactproperty.gen.go +++ b/model/db/artifactproperty.gen.go @@ -8,7 +8,7 @@ const TableNameArtifactProperty = "ArtifactProperty" // ArtifactProperty mapped from table type ArtifactProperty struct { - ArtifactID int32 `gorm:"column:artifact_id;primaryKey" json:"-"` + ArtifactID int64 `gorm:"column:artifact_id;primaryKey" json:"-"` Name string `gorm:"column:name;primaryKey" json:"-"` IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` IntValue *int32 `gorm:"column:int_value" json:"-"` diff --git a/model/db/association.gen.go b/model/db/association.gen.go index 81c7fd95..d46f2cf3 100644 --- a/model/db/association.gen.go +++ b/model/db/association.gen.go @@ -8,9 +8,9 @@ const TableNameAssociation = "Association" // Association mapped from table type Association struct { - ID int32 `gorm:"column:id;primaryKey" json:"-"` - ContextID int32 `gorm:"column:context_id;not null" json:"-"` - ExecutionID int32 `gorm:"column:execution_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey" json:"-"` + ContextID int64 `gorm:"column:context_id;not null" json:"-"` + ExecutionID int64 `gorm:"column:execution_id;not null" json:"-"` } // TableName Association's table name diff --git a/model/db/attribution.gen.go b/model/db/attribution.gen.go index 65ff7718..4d12133c 100644 --- a/model/db/attribution.gen.go +++ b/model/db/attribution.gen.go @@ -8,9 +8,9 @@ const TableNameAttribution = "Attribution" // Attribution mapped from table type Attribution struct { - ID int32 `gorm:"column:id;primaryKey" json:"-"` - ContextID int32 `gorm:"column:context_id;not null" json:"-"` - ArtifactID int32 `gorm:"column:artifact_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey" json:"-"` + ContextID int64 `gorm:"column:context_id;not null" json:"-"` + ArtifactID int64 `gorm:"column:artifact_id;not null" json:"-"` } // TableName Attribution's table name diff --git a/model/db/context.gen.go b/model/db/context.gen.go index a4d51d56..1f90622f 100644 --- a/model/db/context.gen.go +++ b/model/db/context.gen.go @@ -8,8 +8,8 @@ const TableNameContext = "Context" // Context mapped from table type Context struct { - ID int32 `gorm:"column:id;primaryKey" json:"-"` - TypeID int32 `gorm:"column:type_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey" json:"-"` + TypeID int64 `gorm:"column:type_id;not null" json:"-"` Name string `gorm:"column:name;not null" json:"-"` ExternalID string `gorm:"column:external_id;not null" json:"-"` CreateTimeSinceEpoch int32 `gorm:"column:create_time_since_epoch;not null" json:"-"` diff --git a/model/db/contextproperty.gen.go b/model/db/contextproperty.gen.go index 0b739967..1dc87c18 100644 --- a/model/db/contextproperty.gen.go +++ b/model/db/contextproperty.gen.go @@ -8,7 +8,7 @@ const TableNameContextProperty = "ContextProperty" // ContextProperty mapped from table type ContextProperty struct { - ContextID int32 `gorm:"column:context_id;primaryKey" json:"-"` + ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` Name string `gorm:"column:name;not null" json:"-"` IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` IntValue int32 `gorm:"column:int_value;not null" json:"-"` diff --git a/model/db/event.gen.go b/model/db/event.gen.go index be53b3eb..cd878f05 100644 --- a/model/db/event.gen.go +++ b/model/db/event.gen.go @@ -8,9 +8,9 @@ const TableNameEvent = "Event" // Event mapped from table type Event struct { - ID int32 `gorm:"column:id;primaryKey" json:"-"` - ArtifactID int32 `gorm:"column:artifact_id;not null" json:"-"` - ExecutionID int32 `gorm:"column:execution_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey" json:"-"` + ArtifactID int64 `gorm:"column:artifact_id;not null" json:"-"` + ExecutionID int64 `gorm:"column:execution_id;not null" json:"-"` Type int32 `gorm:"column:type;not null" json:"-"` MillisecondsSinceEpoch int32 `gorm:"column:milliseconds_since_epoch;not null" json:"-"` } diff --git a/model/db/eventpath.gen.go b/model/db/eventpath.gen.go index 18f31430..7b3830a2 100644 --- a/model/db/eventpath.gen.go +++ b/model/db/eventpath.gen.go @@ -8,7 +8,7 @@ const TableNameEventPath = "EventPath" // EventPath mapped from table type EventPath struct { - EventID int32 `gorm:"column:event_id;not null" json:"-"` + EventID int64 `gorm:"column:event_id;not null" json:"-"` IsIndexStep int32 `gorm:"column:is_index_step;not null" json:"-"` StepIndex int32 `gorm:"column:step_index;not null" json:"-"` StepKey string `gorm:"column:step_key;not null" json:"-"` diff --git a/model/db/execution.gen.go b/model/db/execution.gen.go index 6c5fb19f..15aaee8f 100644 --- a/model/db/execution.gen.go +++ b/model/db/execution.gen.go @@ -8,8 +8,8 @@ const TableNameExecution = "Execution" // Execution mapped from table type Execution struct { - ID int32 `gorm:"column:id;primaryKey" json:"-"` - TypeID int32 `gorm:"column:type_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey" json:"-"` + TypeID int64 `gorm:"column:type_id;not null" json:"-"` LastKnownState int32 `gorm:"column:last_known_state;not null" json:"-"` Name string `gorm:"column:name;not null" json:"-"` ExternalID string `gorm:"column:external_id;not null" json:"-"` diff --git a/model/db/executionproperty.gen.go b/model/db/executionproperty.gen.go index 74f851bf..27208a3b 100644 --- a/model/db/executionproperty.gen.go +++ b/model/db/executionproperty.gen.go @@ -8,7 +8,7 @@ const TableNameExecutionProperty = "ExecutionProperty" // ExecutionProperty mapped from table type ExecutionProperty struct { - ExecutionID int32 `gorm:"column:execution_id;primaryKey" json:"-"` + ExecutionID int64 `gorm:"column:execution_id;primaryKey" json:"-"` Name string `gorm:"column:name;not null" json:"-"` IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` IntValue int32 `gorm:"column:int_value;not null" json:"-"` diff --git a/model/db/parentcontext.gen.go b/model/db/parentcontext.gen.go index 002f90eb..f8664e19 100644 --- a/model/db/parentcontext.gen.go +++ b/model/db/parentcontext.gen.go @@ -8,8 +8,8 @@ const TableNameParentContext = "ParentContext" // ParentContext mapped from table type ParentContext struct { - ContextID int32 `gorm:"column:context_id;primaryKey" json:"-"` - ParentContextID int32 `gorm:"column:parent_context_id;not null" json:"-"` + ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` + ParentContextID int64 `gorm:"column:parent_context_id;not null" json:"-"` } // TableName ParentContext's table name diff --git a/model/db/parenttype.gen.go b/model/db/parenttype.gen.go index 9a287a7a..7b0c1036 100644 --- a/model/db/parenttype.gen.go +++ b/model/db/parenttype.gen.go @@ -8,8 +8,8 @@ const TableNameParentType = "ParentType" // ParentType mapped from table type ParentType struct { - TypeID int32 `gorm:"column:type_id;primaryKey" json:"-"` - ParentTypeID int32 `gorm:"column:parent_type_id;not null" json:"-"` + TypeID int64 `gorm:"column:type_id;primaryKey" json:"-"` + ParentTypeID int64 `gorm:"column:parent_type_id;not null" json:"-"` } // TableName ParentType's table name diff --git a/model/db/type.gen.go b/model/db/type.gen.go index 5179d952..48dc8a4d 100644 --- a/model/db/type.gen.go +++ b/model/db/type.gen.go @@ -8,7 +8,7 @@ const TableNameType = "Type" // Type mapped from table type Type struct { - ID int32 `gorm:"column:id;primaryKey" json:"-"` + ID int64 `gorm:"column:id;primaryKey" json:"-"` Name string `gorm:"column:name;not null" json:"-"` Version string `gorm:"column:version;not null" json:"-"` TypeKind int32 `gorm:"column:type_kind;not null" json:"-"` diff --git a/model/db/typeproperty.gen.go b/model/db/typeproperty.gen.go index 98f32913..663f6451 100644 --- a/model/db/typeproperty.gen.go +++ b/model/db/typeproperty.gen.go @@ -8,7 +8,7 @@ const TableNameTypeProperty = "TypeProperty" // TypeProperty mapped from table type TypeProperty struct { - TypeID int32 `gorm:"column:type_id;primaryKey" json:"-"` + TypeID int64 `gorm:"column:type_id;primaryKey" json:"-"` Name string `gorm:"column:name;primaryKey;not null" json:"-"` DataType *int32 `gorm:"column:data_type" json:"-"` } diff --git a/server/grpc_server.go b/server/grpc_server.go index e51eff4a..cb1625de 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -58,9 +58,9 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif Name: *artifactType.Name, TypeKind: int32(ARTIFACT_TYPE), } - nilSafeCopy(&value.Version, artifactType.Version, strToStr) - nilSafeCopy(&value.Description, artifactType.Description, strToStr) - nilSafeCopy(&value.ExternalID, artifactType.ExternalId, strToStr) + nilSafeCopy(&value.Version, artifactType.Version, identity[string]) + nilSafeCopy(&value.Description, artifactType.Description, identity[string]) + nilSafeCopy(&value.ExternalID, artifactType.ExternalId, identity[string]) if err = dbConn.Create(value).Error; err != nil { err = fmt.Errorf("error creating artifact type %s: %v", value.Name, err) @@ -89,9 +89,9 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec Name: *executionType.Name, TypeKind: int32(EXECUTION_TYPE), } - nilSafeCopy(&value.Version, executionType.Version, strToStr) - nilSafeCopy(&value.Description, executionType.Description, strToStr) - nilSafeCopy(&value.ExternalID, executionType.ExternalId, strToStr) + nilSafeCopy(&value.Version, executionType.Version, identity[string]) + nilSafeCopy(&value.Description, executionType.Description, identity[string]) + nilSafeCopy(&value.ExternalID, executionType.ExternalId, identity[string]) if err = dbConn.Create(value).Error; err != nil { err = fmt.Errorf("error creating execution type %s: %v", value.Name, err) return nil, err @@ -119,9 +119,9 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex Name: *contextType.Name, TypeKind: int32(CONTEXT_TYPE), } - nilSafeCopy(&value.Version, contextType.Version, strToStr) - nilSafeCopy(&value.Description, contextType.Description, strToStr) - nilSafeCopy(&value.ExternalID, contextType.ExternalId, strToStr) + nilSafeCopy(&value.Version, contextType.Version, identity[string]) + nilSafeCopy(&value.Description, contextType.Description, identity[string]) + nilSafeCopy(&value.ExternalID, contextType.ExternalId, identity[string]) if err = dbConn.Create(value).Error; err != nil { err = fmt.Errorf("error creating context type %s: %v", value.Name, err) return nil, err @@ -203,13 +203,13 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifact return nil, err } value := &db.Artifact{ - TypeID: int32(*artifact.TypeId), + TypeID: *artifact.TypeId, URI: *artifact.Uri, } - nilSafeCopy(&value.ID, artifact.Id, int64ToInt32) + nilSafeCopy(&value.ID, artifact.Id, identity[int64]) nilSafeCopy(&value.State, artifact.State, artifactStateToInt32) - nilSafeCopy(&value.Name, artifact.Name, strToStr) - nilSafeCopy(&value.ExternalID, artifact.ExternalId, strToStr) + nilSafeCopy(&value.Name, artifact.Name, identity[string]) + nilSafeCopy(&value.ExternalID, artifact.ExternalId, identity[string]) // create in DB if err = dbConn.Create(value).Error; err != nil { err = fmt.Errorf("error creating artifact with type_id[%d], name[%s]: %w", value.TypeID, value.Name, err) @@ -491,7 +491,7 @@ func (g grpcServer) createTypeProperties(ctx context.Context, properties map[str return nil } -func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int32, properties map[string]*proto.Value, isCustomProperty bool) (err error) { +func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto.Value, isCustomProperty bool) (err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -537,9 +537,8 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int return nil } -func int64ToInt32(i int64) int32 { return int32(i) } +func identity[T int64 | string](i T) T { return i } func artifactStateToInt32(i proto.Artifact_State) int32 { return int32(i) } -func strToStr(i string) string { return i } func requiredFields(names []string, args ...interface{}) error { var missing []string @@ -554,7 +553,7 @@ func requiredFields(names []string, args ...interface{}) error { return nil } -func nilSafeCopy[D int32 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { +func nilSafeCopy[D int32 | int64 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { if src != nil { *dest = f(*src) } From 3476ac79e341b95ff1f9c2cd191b842cd84ec895 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 1 Sep 2023 10:25:13 -0700 Subject: [PATCH 015/254] Removed unused parent_type table --- cmd/migrate.go | 1 - model/db/parenttype.gen.go | 18 ------------------ 2 files changed, 19 deletions(-) delete mode 100644 model/db/parenttype.gen.go diff --git a/cmd/migrate.go b/cmd/migrate.go index e6da78e1..9f588efb 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -70,7 +70,6 @@ to the latest schema required by this server.`, db.Execution{}, db.ExecutionProperty{}, db.ParentContext{}, - db.ParentType{}, db.Type{}, db.TypeProperty{}, ) diff --git a/model/db/parenttype.gen.go b/model/db/parenttype.gen.go deleted file mode 100644 index 7b0c1036..00000000 --- a/model/db/parenttype.gen.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package db - -const TableNameParentType = "ParentType" - -// ParentType mapped from table -type ParentType struct { - TypeID int64 `gorm:"column:type_id;primaryKey" json:"-"` - ParentTypeID int64 `gorm:"column:parent_type_id;not null" json:"-"` -} - -// TableName ParentType's table name -func (*ParentType) TableName() string { - return TableNameParentType -} From 96799aed22cef54c0172f867f6e488d6c97bdf83 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 1 Sep 2023 21:19:20 -0700 Subject: [PATCH 016/254] Fixed makefile proto rules --- Makefile | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2b48bd7c..d5af94b9 100644 --- a/Makefile +++ b/Makefile @@ -1,24 +1,41 @@ -gen/grpc: api/grpc/ml_metadata/proto/*.proto +ml-metadata-go-server: build + +ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto protoc -I./api/grpc --go_out=. --go_opt=paths=source_relative \ - --go-grpc_out=. --go-grpc_opt=paths=source_relative \ - ml_metadata/proto/metadata_store.proto ml_metadata/proto/metadata_store_service.proto + --go-grpc_out=. --go-grpc_opt=paths=source_relative $< + +.PHONY: gen/grpc +gen/grpc: ml_metadata/proto/metadata_store.pb.go ml_metadata/proto/metadata_store_service.pb.go +.PHONY: clean clean: rm -Rf ml_metadata/proto/*.go ./ml-metadata-go-server +.PHONY: vendor +vendor: + go mod vendor + +.PHONY: build build: gen/grpc go build +.PHONY: gen +gen: gen/grpc + +.PHONY: run/migrate run/migrate: gen/grpc go run main.go migrate --logtostderr=true +.PHONY: run/server run/server: gen/grpc go run main.go serve --logtostderr=true +.PHONY: run/client run/client: gen/grpc python3.9 test/python/test_mlmetadata.py +.PHONY: serve serve: build ./ml-metadata-go-server serve --logtostderr=true -all: build +all: ml-metadata-go-server From bef3c6dea0e71d65f9d2358f4ee9964568695451 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Mon, 4 Sep 2023 23:16:52 -0700 Subject: [PATCH 017/254] Initial mock GraphQL server --- Makefile | 18 +- api/graphql/schema.graphqls | 168 + cmd/serve.go | 209 +- .../mlflow-metadata-library.yaml | 27 + go.mod | 15 +- go.sum | 38 +- gqlgen.yml | 91 + model/graph/models_gen.go | 226 + server/graph/generated.go | 10682 ++++++++++++++++ server/graph/resolver.go | 7 + server/graph/schema.resolvers.go | 70 + tools.go | 9 + 12 files changed, 11468 insertions(+), 92 deletions(-) create mode 100644 api/graphql/schema.graphqls create mode 100644 config/metadata-library/mlflow-metadata-library.yaml create mode 100644 gqlgen.yml create mode 100644 model/graph/models_gen.go create mode 100644 server/graph/generated.go create mode 100644 server/graph/resolver.go create mode 100644 server/graph/schema.resolvers.go create mode 100644 tools.go diff --git a/Makefile b/Makefile index d5af94b9..7efba1ef 100644 --- a/Makefile +++ b/Makefile @@ -7,31 +7,37 @@ ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto .PHONY: gen/grpc gen/grpc: ml_metadata/proto/metadata_store.pb.go ml_metadata/proto/metadata_store_service.pb.go +.PHONY: gen/graph +gen/graph: model/graph/models_gen.go + +model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml + go run github.com/99designs/gqlgen generate + .PHONY: clean clean: - rm -Rf ml_metadata/proto/*.go ./ml-metadata-go-server + rm -Rf ./ml-metadata-go-server ml_metadata/proto/*.go ./model/graph/*.go .PHONY: vendor vendor: go mod vendor .PHONY: build -build: gen/grpc +build: gen go build .PHONY: gen -gen: gen/grpc +gen: gen/grpc gen/graph .PHONY: run/migrate -run/migrate: gen/grpc +run/migrate: gen go run main.go migrate --logtostderr=true .PHONY: run/server -run/server: gen/grpc +run/server: gen go run main.go serve --logtostderr=true .PHONY: run/client -run/client: gen/grpc +run/client: gen python3.9 test/python/test_mlmetadata.py .PHONY: serve diff --git a/api/graphql/schema.graphqls b/api/graphql/schema.graphqls new file mode 100644 index 00000000..8a94177a --- /dev/null +++ b/api/graphql/schema.graphqls @@ -0,0 +1,168 @@ +type Artifact { + id: ID + typeId: ID! + uri: String! + state: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ArtifactType! + properties : [ArtifactProperty!] +} + +type ArtifactProperty { + artifactId: ID + name: String + isCustomProperty: Boolean! + propertyValue: Value! +} + +type Context { + id: ID + typeId: ID! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ContextType! + parent: Context + children: [Context] + attributions: [Artifact!] + associations: [Execution!] + properties: [ContextProperty!] +} + +type ContextProperty { + contextId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +type Event { + id: ID + artifactId: ID! + executionId: ID! + type: Int! + artifact: Artifact + execution: Execution + millisecondsSinceEpoch: Int! +} + +type EventPath { + eventId: ID! + isIndexStep: Int! + stepIndex: Int! + stepKey: String! +} + +type Execution { + id: ID + typeId: ID! + lastKnownState: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ExecutionType! + properties: [ExecutionProperty!] +} + +type ExecutionProperty { + executionId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +union Value = IntValue | DoubleValue | StringValue | BoolValue + +type IntValue { + value: Int! +} + +type DoubleValue { + value: Float! +} + +type StringValue { + value: String! +} + +type BoolValue { + value: Boolean! +} + +interface Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type TypeProperty { + typeId: ID! + name: String! + dataType: Int! +} + +type ArtifactType implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ContextType implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ExecutionType implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +input TypeFilter { + ids: [ID!] + names: [String!] + versions: [String!] + externalIds: [String!] +} + +input InstanceFilter { + ids: [ID!] + typeIds: [ID!] + names: [String!] + externalIds: [String!] +} + +type Query { + types(filter: TypeFilter): [Type!] + artifactTypes(filter: TypeFilter): [ArtifactType!] + contextTypes(filter: TypeFilter): [ContextType!] + executionTypes(filter: TypeFilter): [ExecutionType!] + artifacts(filter: InstanceFilter): [Artifact!] + contexts(filter: InstanceFilter): [Context!] + executions(filter: InstanceFilter): [Execution!] + events: [Event!] +} diff --git a/cmd/serve.go b/cmd/serve.go index 56c9029d..f19417d7 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -18,17 +18,25 @@ package cmd import ( "context" "fmt" + "github.com/99designs/gqlgen/graphql/handler" + "github.com/99designs/gqlgen/graphql/playground" "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" "github.com/dhirajsb/ml-metadata-go-server/server" + "github.com/dhirajsb/ml-metadata-go-server/server/graph" "github.com/golang/glog" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" + "github.com/soheilhy/cmux" "github.com/spf13/cobra" + "golang.org/x/sync/errgroup" "google.golang.org/grpc" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/reflection" "gorm.io/driver/sqlite" "gorm.io/gorm" "log" "net" + "net/http" "os" "os/signal" "syscall" @@ -53,9 +61,9 @@ func InterceptorLogger(l *log.Logger) logging.Logger { } var ( - dbFile string - grpcHost = "localhost" - grpcPort int = 8080 + dbFile string + host = "localhost" + port int = 8080 // serveCmd represents the serve command serveCmd = &cobra.Command{ @@ -65,88 +73,121 @@ var ( The server connects to a SQlite database. It supports options to customize the location of the database file and the hostname and port where it listens.'`, - RunE: func(cmd *cobra.Command, args []string) error { - glog.Info("server started...") - - // Create a channel to receive signals - signalChannel := make(chan os.Signal, 1) - - // Notify the channel on SIGINT (Ctrl+C) and SIGTERM signals - signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) - - // connect to the DB using Gorm - db, err := NewDatabaseConnection(dbFile) - if err != nil { - log.Fatalf("db connection failed: %v", err) - } - - // serve the grpc server - listen, err := net.Listen("tcp", fmt.Sprintf("%s:%d", grpcHost, grpcPort)) - if err != nil { - log.Fatalf("grpc listen failed: %v", err) - } - // TODO map server options from flags - logger := log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile) - lopts := []logging.Option{ - logging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent, logging.StartCall, logging.FinishCall), - // Add any other option (check functions starting with logging.With). - } - opts := []grpc.ServerOption{ - grpc.ChainUnaryInterceptor( - logging.UnaryServerInterceptor(InterceptorLogger(logger), lopts...), - ), - grpc.ChainStreamInterceptor( - logging.StreamServerInterceptor(InterceptorLogger(logger), lopts...), - ), - } - - grpcServer := grpc.NewServer(opts...) - proto.RegisterMetadataStoreServiceServer(grpcServer, server.NewGrpcServer(db)) - reflection.Register(grpcServer) - - go func() { - glog.Info("Starting grpc server...") - err = grpcServer.Serve(listen) - if err != nil { - glog.Errorf("grpc serving failed: %v", err) - signalChannel <- syscall.SIGTERM - } - }() - - // TODO serve the GraphQL server - - // error starting server - if err != nil { - return err - } - - // Wait for a signal - receivedSignal := <-signalChannel - glog.Infof("received signal: %s\n", receivedSignal) - - // Perform cleanup or other graceful shutdown actions here - glog.Info("shutting down services...") - - // stop grpc server - grpcServer.Stop() - // TODO stop graphql server - - // close DB - glog.Info("closing DB...") - sqlDB, err := db.DB() - if err != nil { - return fmt.Errorf("error accessing DB: %v", err) - } - err = sqlDB.Close() - if err != nil { - return fmt.Errorf("error closing DB: %v", err) - } - glog.Info("shutdown!") - return nil - }, + RunE: runServer, } ) +func runServer(cmd *cobra.Command, args []string) error { + glog.Info("server started...") + + // Create a channel to receive signals + signalChannel := make(chan os.Signal, 1) + + // Notify the channel on SIGINT (Ctrl+C) and SIGTERM signals + signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) + + // connect to the DB using Gorm + db, err := NewDatabaseConnection(dbFile) + if err != nil { + log.Fatalf("db connection failed: %v", err) + } + + // listen on host:port + listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port)) + if err != nil { + log.Fatalf("server listen failed: %v", err) + } + m := cmux.New(listener) + grpcListener := m.Match(cmux.HTTP2HeaderField("content-type", "application/grpc")) + gqlListener := m.Match(cmux.HTTP1Fast()) + + // gRPC server + grpcServer := grpcListenerServer(grpcListener, server.NewGrpcServer(db)) + // GraphQL server + gqlServer := graphQlListenerServer(grpcListener, db) + + // start cmux listeners + g := new(errgroup.Group) + g.Go(func() error { + glog.Info("starting gRPC server...") + return grpcServer.Serve(listener) + }) + g.Go(func() error { + glog.Info("starting GraphQL server...") + return gqlServer.Serve(gqlListener) + }) + g.Go(func() error { + return m.Serve() + }) + + go func() { + err = g.Wait() + // error starting server + if err != nil || err != http.ErrServerClosed || err != grpc.ErrServerStopped || err != cmux.ErrServerClosed { + glog.Errorf("server listener error: %v", err) + } + signalChannel <- syscall.SIGINT + }() + + // Wait for a signal + receivedSignal := <-signalChannel + glog.Infof("received signal: %s\n", receivedSignal) + + // Perform cleanup or other graceful shutdown actions here + glog.Info("shutting down services...") + grpcServer.Stop() + _ = gqlServer.Shutdown(context.Background()) + + // close DB + glog.Info("closing DB...") + sqlDB, err := db.DB() + if err != nil { + return fmt.Errorf("error accessing DB: %v", err) + } + err = sqlDB.Close() + if err != nil { + return fmt.Errorf("error closing DB: %v", err) + } + glog.Info("shutdown!") + return nil +} + +func graphQlListenerServer(listener net.Listener, db *gorm.DB) *http.Server { + mux := http.NewServeMux() + srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})) + + mux.Handle("/", playground.Handler("GraphQL playground", "/query")) + mux.Handle("/query", srv) + + return &http.Server{Handler: mux} +} + +func grpcListenerServer(listener net.Listener, server proto.MetadataStoreServiceServer) *grpc.Server { + // TODO map server options from flags + logger := log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile) + lopts := []logging.Option{ + logging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent, logging.StartCall, logging.FinishCall), + // Add any other option (check functions starting with logging.With). + } + opts := []grpc.ServerOption{ + grpc.ChainUnaryInterceptor( + logging.UnaryServerInterceptor(InterceptorLogger(logger), lopts...), + ), + grpc.ChainStreamInterceptor( + logging.StreamServerInterceptor(InterceptorLogger(logger), lopts...), + ), + } + + grpcServer := grpc.NewServer(opts...) + // simple health check + grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer()) + + proto.RegisterMetadataStoreServiceServer(grpcServer, server) + reflection.Register(grpcServer) + + return grpcServer +} + func NewDatabaseConnection(dbFile string) (*gorm.DB, error) { return gorm.Open(sqlite.Open(dbFile), &gorm.Config{}) } @@ -163,6 +204,6 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: serveCmd.Flags().StringVarP(&dbFile, "db-file", "d", "metadata.sqlite.db", "Sqlite DB file") - serveCmd.Flags().StringVarP(&grpcHost, "grpc-host", "h", grpcHost, "gRPC listen hostname") - serveCmd.Flags().IntVarP(&grpcPort, "grpc-port", "p", grpcPort, "gRPC listen port") + serveCmd.Flags().StringVarP(&host, "hostname", "n", host, "Server listen hostname") + serveCmd.Flags().IntVarP(&port, "port", "p", port, "Server listen port") } diff --git a/config/metadata-library/mlflow-metadata-library.yaml b/config/metadata-library/mlflow-metadata-library.yaml new file mode 100644 index 00000000..b0ec693e --- /dev/null +++ b/config/metadata-library/mlflow-metadata-library.yaml @@ -0,0 +1,27 @@ +# types for ml-metadata library +artifact-types: + - name: "mlflow.Model" + - name: "mlflow.ModelEvaluation" + - name: "mlflow.EvaluationMeasure" + - name: "mlflow.EvaluationSpecification" + - name: "mlflow.EvaluationProcedure" + - name: "mlflow.Task" + - name: "mlflow.Data" + - name: "mlflow.DataSet" + - name: "mlflow.Feature" + - name: "mlflow.Algorithm" + - name: "mlflow.Software" + - name: "mlflow.Implementation" + - name: "mlflow.HyperParameter" + - name: "mlflow.HyperParameterSetting" + - name: "mlflow.ImplementationCharacteristic" + - name: "mlflow.DatasetCharacteristic" + - name: "mlflow.FeatureCharacteristic" +context-types: + - name: "mlflow.RegisteredModel" + - name: "mlflow.ModelVersion" + - name: "mlflow.DataCharacteristic" +execution-types: + - name: "mlflow.Study" + - name: "mlflow.Experiment" + - name: "mlflow.Run" diff --git a/go.mod b/go.mod index 0d8f855f..670d6190 100644 --- a/go.mod +++ b/go.mod @@ -3,19 +3,28 @@ module github.com/dhirajsb/ml-metadata-go-server go 1.19 require ( + github.com/99designs/gqlgen v0.17.36 github.com/golang/glog v1.1.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 + github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 + github.com/vektah/gqlparser/v2 v2.5.8 + golang.org/x/sync v0.2.0 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 + gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/sqlite v1.5.3 gorm.io/gorm v1.25.4 ) require ( + github.com/agnivade/levenshtein v1.1.1 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect @@ -24,15 +33,19 @@ require ( github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect + github.com/urfave/cli/v2 v2.25.5 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.14.0 // indirect golang.org/x/sys v0.11.0 // indirect golang.org/x/text v0.12.0 // indirect + golang.org/x/tools v0.9.3 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 9750d540..3c29015f 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,16 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/99designs/gqlgen v0.17.36 h1:u/o/rv2SZ9s5280dyUOOrkpIIkr/7kITMXYD3rkJ9go= +github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= +github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= +github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= +github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -46,10 +54,13 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= +github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -123,10 +134,14 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 h1:2cz5kSrxzMYHiWOBbKj8itQm+nRykkB8aMv4ThcHYHA= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE= +github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -161,7 +176,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= @@ -187,6 +207,12 @@ github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc= +github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/vektah/gqlparser/v2 v2.5.8 h1:pm6WOnGdzFOCfcQo9L3+xzW51mKrlwTEg4Wr7AH1JW4= +github.com/vektah/gqlparser/v2 v2.5.8/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -237,6 +263,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -265,6 +293,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -290,6 +319,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -389,6 +420,8 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= +golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -490,12 +523,15 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/gqlgen.yml b/gqlgen.yml new file mode 100644 index 00000000..b8f9430e --- /dev/null +++ b/gqlgen.yml @@ -0,0 +1,91 @@ +# Where are all the schema files located? globs are supported eg src/**/*.graphqls +schema: + - api/graphql/*.graphqls + +# Where should the generated server code go? +exec: + filename: server/graph/generated.go + package: graph + +# Uncomment to enable federation +# federation: +# filename: graph/federation.go +# package: graph + +# Where should any generated models go? +model: + filename: model/graph/models_gen.go + package: graph + +# Where should the resolver implementations go? +resolver: + layout: follow-schema + dir: server/graph + package: graph + filename_template: "{name}.resolvers.go" + # Optional: turn on to not generate template comments above resolvers + # omit_template_comment: false + +# Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models +# struct_tag: json + +# Optional: turn on to use []Thing instead of []*Thing +# omit_slice_element_pointers: false + +# Optional: turn on to omit Is() methods to interface and unions +# omit_interface_checks : true + +# Optional: turn on to skip generation of ComplexityRoot struct content and Complexity function +# omit_complexity: false + +# Optional: turn on to not generate any file notice comments in generated files +# omit_gqlgen_file_notice: false + +# Optional: turn on to exclude the gqlgen version in the generated file notice. No effect if `omit_gqlgen_file_notice` is true. +# omit_gqlgen_version_in_file_notice: false + +# Optional: turn off to make struct-type struct fields not use pointers +# e.g. type Thing struct { FieldA OtherThing } instead of { FieldA *OtherThing } +# struct_fields_always_pointers: true + +# Optional: turn off to make resolvers return values instead of pointers for structs +# resolvers_always_return_pointers: true + +# Optional: turn on to return pointers instead of values in unmarshalInput +# return_pointers_in_unmarshalinput: false + +# Optional: wrap nullable input fields with Omittable +# nullable_input_omittable: true + +# Optional: set to speed up generation time by not performing a final validation pass. +# skip_validation: true + +# Optional: set to skip running `go mod tidy` when generating server code +# skip_mod_tidy: true + +# gqlgen will search for any type names in the schema in these go packages +# if they match it will use them, otherwise it will generate them. +autobind: +# - "github.com/dhirajsb/ml-metadata-go-server/graph/model" + +# This section declares type mapping between the GraphQL and go type systems +# +# The first line in each type will be used as defaults for resolver arguments and +# modelgen, the others will be allowed when binding to fields. Configure them to +# your liking +models: + ID: + model: + - github.com/99designs/gqlgen/graphql.ID + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Int: + model: + - github.com/99designs/gqlgen/graphql.Int + - github.com/99designs/gqlgen/graphql.Int64 + - github.com/99designs/gqlgen/graphql.Int32 + Artifact: + fields: + type: + resolver: true \ No newline at end of file diff --git a/model/graph/models_gen.go b/model/graph/models_gen.go new file mode 100644 index 00000000..c54f1ebe --- /dev/null +++ b/model/graph/models_gen.go @@ -0,0 +1,226 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package graph + +type Type interface { + IsType() + GetID() *string + GetName() string + GetVersion() string + GetTypeKind() int + GetDescription() string + GetExternalID() *string + GetProperties() []*TypeProperty +} + +type Value interface { + IsValue() +} + +type Artifact struct { + ID *string `json:"id,omitempty"` + TypeID string `json:"typeId"` + URI string `json:"uri"` + State int `json:"state"` + Name string `json:"name"` + ExternalID *string `json:"externalId,omitempty"` + CreateTimeSinceEpoch int `json:"createTimeSinceEpoch"` + LastUpdateTimeSinceEpoch int `json:"lastUpdateTimeSinceEpoch"` + Type *ArtifactType `json:"type"` + Properties []*ArtifactProperty `json:"properties,omitempty"` +} + +type ArtifactProperty struct { + ArtifactID *string `json:"artifactId,omitempty"` + Name *string `json:"name,omitempty"` + IsCustomProperty bool `json:"isCustomProperty"` + PropertyValue Value `json:"propertyValue"` +} + +type ArtifactType struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (ArtifactType) IsType() {} +func (this ArtifactType) GetID() *string { return this.ID } +func (this ArtifactType) GetName() string { return this.Name } +func (this ArtifactType) GetVersion() string { return this.Version } +func (this ArtifactType) GetTypeKind() int { return this.TypeKind } +func (this ArtifactType) GetDescription() string { return this.Description } +func (this ArtifactType) GetExternalID() *string { return this.ExternalID } +func (this ArtifactType) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +type BoolValue struct { + Value bool `json:"value"` +} + +func (BoolValue) IsValue() {} + +type Context struct { + ID *string `json:"id,omitempty"` + TypeID string `json:"typeId"` + Name string `json:"name"` + ExternalID *string `json:"externalId,omitempty"` + CreateTimeSinceEpoch int `json:"createTimeSinceEpoch"` + LastUpdateTimeSinceEpoch int `json:"lastUpdateTimeSinceEpoch"` + Type *ContextType `json:"type"` + Parent *Context `json:"parent,omitempty"` + Children []*Context `json:"children,omitempty"` + Attributions []*Artifact `json:"attributions,omitempty"` + Associations []*Execution `json:"associations,omitempty"` + Properties []*ContextProperty `json:"properties,omitempty"` +} + +type ContextProperty struct { + ContextID *string `json:"contextId,omitempty"` + Name string `json:"name"` + IsCustomProperty int `json:"isCustomProperty"` + PropertyValue Value `json:"propertyValue"` +} + +type ContextType struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (ContextType) IsType() {} +func (this ContextType) GetID() *string { return this.ID } +func (this ContextType) GetName() string { return this.Name } +func (this ContextType) GetVersion() string { return this.Version } +func (this ContextType) GetTypeKind() int { return this.TypeKind } +func (this ContextType) GetDescription() string { return this.Description } +func (this ContextType) GetExternalID() *string { return this.ExternalID } +func (this ContextType) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +type DoubleValue struct { + Value float64 `json:"value"` +} + +func (DoubleValue) IsValue() {} + +type Event struct { + ID *string `json:"id,omitempty"` + ArtifactID string `json:"artifactId"` + ExecutionID string `json:"executionId"` + Type int `json:"type"` + Artifact *Artifact `json:"artifact,omitempty"` + Execution *Execution `json:"execution,omitempty"` + MillisecondsSinceEpoch int `json:"millisecondsSinceEpoch"` +} + +type EventPath struct { + EventID string `json:"eventId"` + IsIndexStep int `json:"isIndexStep"` + StepIndex int `json:"stepIndex"` + StepKey string `json:"stepKey"` +} + +type Execution struct { + ID *string `json:"id,omitempty"` + TypeID string `json:"typeId"` + LastKnownState int `json:"lastKnownState"` + Name string `json:"name"` + ExternalID *string `json:"externalId,omitempty"` + CreateTimeSinceEpoch int `json:"createTimeSinceEpoch"` + LastUpdateTimeSinceEpoch int `json:"lastUpdateTimeSinceEpoch"` + Type *ExecutionType `json:"type"` + Properties []*ExecutionProperty `json:"properties,omitempty"` +} + +type ExecutionProperty struct { + ExecutionID *string `json:"executionId,omitempty"` + Name string `json:"name"` + IsCustomProperty int `json:"isCustomProperty"` + PropertyValue Value `json:"propertyValue"` +} + +type ExecutionType struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + InputType string `json:"inputType"` + OutputType string `json:"outputType"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (ExecutionType) IsType() {} +func (this ExecutionType) GetID() *string { return this.ID } +func (this ExecutionType) GetName() string { return this.Name } +func (this ExecutionType) GetVersion() string { return this.Version } +func (this ExecutionType) GetTypeKind() int { return this.TypeKind } +func (this ExecutionType) GetDescription() string { return this.Description } +func (this ExecutionType) GetExternalID() *string { return this.ExternalID } +func (this ExecutionType) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +type InstanceFilter struct { + Ids []string `json:"ids,omitempty"` + TypeIds []string `json:"typeIds,omitempty"` + Names []string `json:"names,omitempty"` + ExternalIds []string `json:"externalIds,omitempty"` +} + +type IntValue struct { + Value int `json:"value"` +} + +func (IntValue) IsValue() {} + +type StringValue struct { + Value string `json:"value"` +} + +func (StringValue) IsValue() {} + +type TypeFilter struct { + Ids []string `json:"ids,omitempty"` + Names []string `json:"names,omitempty"` + Versions []string `json:"versions,omitempty"` + ExternalIds []string `json:"externalIds,omitempty"` +} + +type TypeProperty struct { + TypeID string `json:"typeId"` + Name string `json:"name"` + DataType int `json:"dataType"` +} diff --git a/server/graph/generated.go b/server/graph/generated.go new file mode 100644 index 00000000..6babac01 --- /dev/null +++ b/server/graph/generated.go @@ -0,0 +1,10682 @@ +// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. + +package graph + +import ( + "bytes" + "context" + "errors" + "fmt" + "strconv" + "sync" + "sync/atomic" + + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/introspection" + "github.com/dhirajsb/ml-metadata-go-server/model/graph" + gqlparser "github.com/vektah/gqlparser/v2" + "github.com/vektah/gqlparser/v2/ast" +) + +// region ************************** generated!.gotpl ************************** + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + resolvers: cfg.Resolvers, + directives: cfg.Directives, + complexity: cfg.Complexity, + } +} + +type Config struct { + Resolvers ResolverRoot + Directives DirectiveRoot + Complexity ComplexityRoot +} + +type ResolverRoot interface { + Artifact() ArtifactResolver + Query() QueryResolver +} + +type DirectiveRoot struct { +} + +type ComplexityRoot struct { + Artifact struct { + CreateTimeSinceEpoch func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + LastUpdateTimeSinceEpoch func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + State func(childComplexity int) int + Type func(childComplexity int) int + TypeID func(childComplexity int) int + URI func(childComplexity int) int + } + + ArtifactProperty struct { + ArtifactID func(childComplexity int) int + IsCustomProperty func(childComplexity int) int + Name func(childComplexity int) int + PropertyValue func(childComplexity int) int + } + + ArtifactType struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + BoolValue struct { + Value func(childComplexity int) int + } + + Context struct { + Associations func(childComplexity int) int + Attributions func(childComplexity int) int + Children func(childComplexity int) int + CreateTimeSinceEpoch func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + LastUpdateTimeSinceEpoch func(childComplexity int) int + Name func(childComplexity int) int + Parent func(childComplexity int) int + Properties func(childComplexity int) int + Type func(childComplexity int) int + TypeID func(childComplexity int) int + } + + ContextProperty struct { + ContextID func(childComplexity int) int + IsCustomProperty func(childComplexity int) int + Name func(childComplexity int) int + PropertyValue func(childComplexity int) int + } + + ContextType struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + DoubleValue struct { + Value func(childComplexity int) int + } + + Event struct { + Artifact func(childComplexity int) int + ArtifactID func(childComplexity int) int + Execution func(childComplexity int) int + ExecutionID func(childComplexity int) int + ID func(childComplexity int) int + MillisecondsSinceEpoch func(childComplexity int) int + Type func(childComplexity int) int + } + + EventPath struct { + EventID func(childComplexity int) int + IsIndexStep func(childComplexity int) int + StepIndex func(childComplexity int) int + StepKey func(childComplexity int) int + } + + Execution struct { + CreateTimeSinceEpoch func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + LastKnownState func(childComplexity int) int + LastUpdateTimeSinceEpoch func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + Type func(childComplexity int) int + TypeID func(childComplexity int) int + } + + ExecutionProperty struct { + ExecutionID func(childComplexity int) int + IsCustomProperty func(childComplexity int) int + Name func(childComplexity int) int + PropertyValue func(childComplexity int) int + } + + ExecutionType struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + InputType func(childComplexity int) int + Name func(childComplexity int) int + OutputType func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + IntValue struct { + Value func(childComplexity int) int + } + + Query struct { + ArtifactTypes func(childComplexity int, filter *graph.TypeFilter) int + Artifacts func(childComplexity int, filter *graph.InstanceFilter) int + ContextTypes func(childComplexity int, filter *graph.TypeFilter) int + Contexts func(childComplexity int, filter *graph.InstanceFilter) int + Events func(childComplexity int) int + ExecutionTypes func(childComplexity int, filter *graph.TypeFilter) int + Executions func(childComplexity int, filter *graph.InstanceFilter) int + Types func(childComplexity int, filter *graph.TypeFilter) int + } + + StringValue struct { + Value func(childComplexity int) int + } + + TypeProperty struct { + DataType func(childComplexity int) int + Name func(childComplexity int) int + TypeID func(childComplexity int) int + } +} + +type ArtifactResolver interface { + Type(ctx context.Context, obj *graph.Artifact) (*graph.ArtifactType, error) +} +type QueryResolver interface { + Types(ctx context.Context, filter *graph.TypeFilter) ([]graph.Type, error) + ArtifactTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ArtifactType, error) + ContextTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ContextType, error) + ExecutionTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ExecutionType, error) + Artifacts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Artifact, error) + Contexts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Context, error) + Executions(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Execution, error) + Events(ctx context.Context) ([]*graph.Event, error) +} + +type executableSchema struct { + resolvers ResolverRoot + directives DirectiveRoot + complexity ComplexityRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + return parsedSchema +} + +func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { + ec := executionContext{nil, e, 0, 0, nil} + _ = ec + switch typeName + "." + field { + + case "Artifact.createTimeSinceEpoch": + if e.complexity.Artifact.CreateTimeSinceEpoch == nil { + break + } + + return e.complexity.Artifact.CreateTimeSinceEpoch(childComplexity), true + + case "Artifact.externalId": + if e.complexity.Artifact.ExternalID == nil { + break + } + + return e.complexity.Artifact.ExternalID(childComplexity), true + + case "Artifact.id": + if e.complexity.Artifact.ID == nil { + break + } + + return e.complexity.Artifact.ID(childComplexity), true + + case "Artifact.lastUpdateTimeSinceEpoch": + if e.complexity.Artifact.LastUpdateTimeSinceEpoch == nil { + break + } + + return e.complexity.Artifact.LastUpdateTimeSinceEpoch(childComplexity), true + + case "Artifact.name": + if e.complexity.Artifact.Name == nil { + break + } + + return e.complexity.Artifact.Name(childComplexity), true + + case "Artifact.properties": + if e.complexity.Artifact.Properties == nil { + break + } + + return e.complexity.Artifact.Properties(childComplexity), true + + case "Artifact.state": + if e.complexity.Artifact.State == nil { + break + } + + return e.complexity.Artifact.State(childComplexity), true + + case "Artifact.type": + if e.complexity.Artifact.Type == nil { + break + } + + return e.complexity.Artifact.Type(childComplexity), true + + case "Artifact.typeId": + if e.complexity.Artifact.TypeID == nil { + break + } + + return e.complexity.Artifact.TypeID(childComplexity), true + + case "Artifact.uri": + if e.complexity.Artifact.URI == nil { + break + } + + return e.complexity.Artifact.URI(childComplexity), true + + case "ArtifactProperty.artifactId": + if e.complexity.ArtifactProperty.ArtifactID == nil { + break + } + + return e.complexity.ArtifactProperty.ArtifactID(childComplexity), true + + case "ArtifactProperty.isCustomProperty": + if e.complexity.ArtifactProperty.IsCustomProperty == nil { + break + } + + return e.complexity.ArtifactProperty.IsCustomProperty(childComplexity), true + + case "ArtifactProperty.name": + if e.complexity.ArtifactProperty.Name == nil { + break + } + + return e.complexity.ArtifactProperty.Name(childComplexity), true + + case "ArtifactProperty.propertyValue": + if e.complexity.ArtifactProperty.PropertyValue == nil { + break + } + + return e.complexity.ArtifactProperty.PropertyValue(childComplexity), true + + case "ArtifactType.description": + if e.complexity.ArtifactType.Description == nil { + break + } + + return e.complexity.ArtifactType.Description(childComplexity), true + + case "ArtifactType.externalId": + if e.complexity.ArtifactType.ExternalID == nil { + break + } + + return e.complexity.ArtifactType.ExternalID(childComplexity), true + + case "ArtifactType.id": + if e.complexity.ArtifactType.ID == nil { + break + } + + return e.complexity.ArtifactType.ID(childComplexity), true + + case "ArtifactType.name": + if e.complexity.ArtifactType.Name == nil { + break + } + + return e.complexity.ArtifactType.Name(childComplexity), true + + case "ArtifactType.properties": + if e.complexity.ArtifactType.Properties == nil { + break + } + + return e.complexity.ArtifactType.Properties(childComplexity), true + + case "ArtifactType.typeKind": + if e.complexity.ArtifactType.TypeKind == nil { + break + } + + return e.complexity.ArtifactType.TypeKind(childComplexity), true + + case "ArtifactType.version": + if e.complexity.ArtifactType.Version == nil { + break + } + + return e.complexity.ArtifactType.Version(childComplexity), true + + case "BoolValue.value": + if e.complexity.BoolValue.Value == nil { + break + } + + return e.complexity.BoolValue.Value(childComplexity), true + + case "Context.associations": + if e.complexity.Context.Associations == nil { + break + } + + return e.complexity.Context.Associations(childComplexity), true + + case "Context.attributions": + if e.complexity.Context.Attributions == nil { + break + } + + return e.complexity.Context.Attributions(childComplexity), true + + case "Context.children": + if e.complexity.Context.Children == nil { + break + } + + return e.complexity.Context.Children(childComplexity), true + + case "Context.createTimeSinceEpoch": + if e.complexity.Context.CreateTimeSinceEpoch == nil { + break + } + + return e.complexity.Context.CreateTimeSinceEpoch(childComplexity), true + + case "Context.externalId": + if e.complexity.Context.ExternalID == nil { + break + } + + return e.complexity.Context.ExternalID(childComplexity), true + + case "Context.id": + if e.complexity.Context.ID == nil { + break + } + + return e.complexity.Context.ID(childComplexity), true + + case "Context.lastUpdateTimeSinceEpoch": + if e.complexity.Context.LastUpdateTimeSinceEpoch == nil { + break + } + + return e.complexity.Context.LastUpdateTimeSinceEpoch(childComplexity), true + + case "Context.name": + if e.complexity.Context.Name == nil { + break + } + + return e.complexity.Context.Name(childComplexity), true + + case "Context.parent": + if e.complexity.Context.Parent == nil { + break + } + + return e.complexity.Context.Parent(childComplexity), true + + case "Context.properties": + if e.complexity.Context.Properties == nil { + break + } + + return e.complexity.Context.Properties(childComplexity), true + + case "Context.type": + if e.complexity.Context.Type == nil { + break + } + + return e.complexity.Context.Type(childComplexity), true + + case "Context.typeId": + if e.complexity.Context.TypeID == nil { + break + } + + return e.complexity.Context.TypeID(childComplexity), true + + case "ContextProperty.contextId": + if e.complexity.ContextProperty.ContextID == nil { + break + } + + return e.complexity.ContextProperty.ContextID(childComplexity), true + + case "ContextProperty.isCustomProperty": + if e.complexity.ContextProperty.IsCustomProperty == nil { + break + } + + return e.complexity.ContextProperty.IsCustomProperty(childComplexity), true + + case "ContextProperty.name": + if e.complexity.ContextProperty.Name == nil { + break + } + + return e.complexity.ContextProperty.Name(childComplexity), true + + case "ContextProperty.propertyValue": + if e.complexity.ContextProperty.PropertyValue == nil { + break + } + + return e.complexity.ContextProperty.PropertyValue(childComplexity), true + + case "ContextType.description": + if e.complexity.ContextType.Description == nil { + break + } + + return e.complexity.ContextType.Description(childComplexity), true + + case "ContextType.externalId": + if e.complexity.ContextType.ExternalID == nil { + break + } + + return e.complexity.ContextType.ExternalID(childComplexity), true + + case "ContextType.id": + if e.complexity.ContextType.ID == nil { + break + } + + return e.complexity.ContextType.ID(childComplexity), true + + case "ContextType.name": + if e.complexity.ContextType.Name == nil { + break + } + + return e.complexity.ContextType.Name(childComplexity), true + + case "ContextType.properties": + if e.complexity.ContextType.Properties == nil { + break + } + + return e.complexity.ContextType.Properties(childComplexity), true + + case "ContextType.typeKind": + if e.complexity.ContextType.TypeKind == nil { + break + } + + return e.complexity.ContextType.TypeKind(childComplexity), true + + case "ContextType.version": + if e.complexity.ContextType.Version == nil { + break + } + + return e.complexity.ContextType.Version(childComplexity), true + + case "DoubleValue.value": + if e.complexity.DoubleValue.Value == nil { + break + } + + return e.complexity.DoubleValue.Value(childComplexity), true + + case "Event.artifact": + if e.complexity.Event.Artifact == nil { + break + } + + return e.complexity.Event.Artifact(childComplexity), true + + case "Event.artifactId": + if e.complexity.Event.ArtifactID == nil { + break + } + + return e.complexity.Event.ArtifactID(childComplexity), true + + case "Event.execution": + if e.complexity.Event.Execution == nil { + break + } + + return e.complexity.Event.Execution(childComplexity), true + + case "Event.executionId": + if e.complexity.Event.ExecutionID == nil { + break + } + + return e.complexity.Event.ExecutionID(childComplexity), true + + case "Event.id": + if e.complexity.Event.ID == nil { + break + } + + return e.complexity.Event.ID(childComplexity), true + + case "Event.millisecondsSinceEpoch": + if e.complexity.Event.MillisecondsSinceEpoch == nil { + break + } + + return e.complexity.Event.MillisecondsSinceEpoch(childComplexity), true + + case "Event.type": + if e.complexity.Event.Type == nil { + break + } + + return e.complexity.Event.Type(childComplexity), true + + case "EventPath.eventId": + if e.complexity.EventPath.EventID == nil { + break + } + + return e.complexity.EventPath.EventID(childComplexity), true + + case "EventPath.isIndexStep": + if e.complexity.EventPath.IsIndexStep == nil { + break + } + + return e.complexity.EventPath.IsIndexStep(childComplexity), true + + case "EventPath.stepIndex": + if e.complexity.EventPath.StepIndex == nil { + break + } + + return e.complexity.EventPath.StepIndex(childComplexity), true + + case "EventPath.stepKey": + if e.complexity.EventPath.StepKey == nil { + break + } + + return e.complexity.EventPath.StepKey(childComplexity), true + + case "Execution.createTimeSinceEpoch": + if e.complexity.Execution.CreateTimeSinceEpoch == nil { + break + } + + return e.complexity.Execution.CreateTimeSinceEpoch(childComplexity), true + + case "Execution.externalId": + if e.complexity.Execution.ExternalID == nil { + break + } + + return e.complexity.Execution.ExternalID(childComplexity), true + + case "Execution.id": + if e.complexity.Execution.ID == nil { + break + } + + return e.complexity.Execution.ID(childComplexity), true + + case "Execution.lastKnownState": + if e.complexity.Execution.LastKnownState == nil { + break + } + + return e.complexity.Execution.LastKnownState(childComplexity), true + + case "Execution.lastUpdateTimeSinceEpoch": + if e.complexity.Execution.LastUpdateTimeSinceEpoch == nil { + break + } + + return e.complexity.Execution.LastUpdateTimeSinceEpoch(childComplexity), true + + case "Execution.name": + if e.complexity.Execution.Name == nil { + break + } + + return e.complexity.Execution.Name(childComplexity), true + + case "Execution.properties": + if e.complexity.Execution.Properties == nil { + break + } + + return e.complexity.Execution.Properties(childComplexity), true + + case "Execution.type": + if e.complexity.Execution.Type == nil { + break + } + + return e.complexity.Execution.Type(childComplexity), true + + case "Execution.typeId": + if e.complexity.Execution.TypeID == nil { + break + } + + return e.complexity.Execution.TypeID(childComplexity), true + + case "ExecutionProperty.executionId": + if e.complexity.ExecutionProperty.ExecutionID == nil { + break + } + + return e.complexity.ExecutionProperty.ExecutionID(childComplexity), true + + case "ExecutionProperty.isCustomProperty": + if e.complexity.ExecutionProperty.IsCustomProperty == nil { + break + } + + return e.complexity.ExecutionProperty.IsCustomProperty(childComplexity), true + + case "ExecutionProperty.name": + if e.complexity.ExecutionProperty.Name == nil { + break + } + + return e.complexity.ExecutionProperty.Name(childComplexity), true + + case "ExecutionProperty.propertyValue": + if e.complexity.ExecutionProperty.PropertyValue == nil { + break + } + + return e.complexity.ExecutionProperty.PropertyValue(childComplexity), true + + case "ExecutionType.description": + if e.complexity.ExecutionType.Description == nil { + break + } + + return e.complexity.ExecutionType.Description(childComplexity), true + + case "ExecutionType.externalId": + if e.complexity.ExecutionType.ExternalID == nil { + break + } + + return e.complexity.ExecutionType.ExternalID(childComplexity), true + + case "ExecutionType.id": + if e.complexity.ExecutionType.ID == nil { + break + } + + return e.complexity.ExecutionType.ID(childComplexity), true + + case "ExecutionType.inputType": + if e.complexity.ExecutionType.InputType == nil { + break + } + + return e.complexity.ExecutionType.InputType(childComplexity), true + + case "ExecutionType.name": + if e.complexity.ExecutionType.Name == nil { + break + } + + return e.complexity.ExecutionType.Name(childComplexity), true + + case "ExecutionType.outputType": + if e.complexity.ExecutionType.OutputType == nil { + break + } + + return e.complexity.ExecutionType.OutputType(childComplexity), true + + case "ExecutionType.properties": + if e.complexity.ExecutionType.Properties == nil { + break + } + + return e.complexity.ExecutionType.Properties(childComplexity), true + + case "ExecutionType.typeKind": + if e.complexity.ExecutionType.TypeKind == nil { + break + } + + return e.complexity.ExecutionType.TypeKind(childComplexity), true + + case "ExecutionType.version": + if e.complexity.ExecutionType.Version == nil { + break + } + + return e.complexity.ExecutionType.Version(childComplexity), true + + case "IntValue.value": + if e.complexity.IntValue.Value == nil { + break + } + + return e.complexity.IntValue.Value(childComplexity), true + + case "Query.artifactTypes": + if e.complexity.Query.ArtifactTypes == nil { + break + } + + args, err := ec.field_Query_artifactTypes_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ArtifactTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true + + case "Query.artifacts": + if e.complexity.Query.Artifacts == nil { + break + } + + args, err := ec.field_Query_artifacts_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Artifacts(childComplexity, args["filter"].(*graph.InstanceFilter)), true + + case "Query.contextTypes": + if e.complexity.Query.ContextTypes == nil { + break + } + + args, err := ec.field_Query_contextTypes_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ContextTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true + + case "Query.contexts": + if e.complexity.Query.Contexts == nil { + break + } + + args, err := ec.field_Query_contexts_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Contexts(childComplexity, args["filter"].(*graph.InstanceFilter)), true + + case "Query.events": + if e.complexity.Query.Events == nil { + break + } + + return e.complexity.Query.Events(childComplexity), true + + case "Query.executionTypes": + if e.complexity.Query.ExecutionTypes == nil { + break + } + + args, err := ec.field_Query_executionTypes_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.ExecutionTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true + + case "Query.executions": + if e.complexity.Query.Executions == nil { + break + } + + args, err := ec.field_Query_executions_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Executions(childComplexity, args["filter"].(*graph.InstanceFilter)), true + + case "Query.types": + if e.complexity.Query.Types == nil { + break + } + + args, err := ec.field_Query_types_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Types(childComplexity, args["filter"].(*graph.TypeFilter)), true + + case "StringValue.value": + if e.complexity.StringValue.Value == nil { + break + } + + return e.complexity.StringValue.Value(childComplexity), true + + case "TypeProperty.dataType": + if e.complexity.TypeProperty.DataType == nil { + break + } + + return e.complexity.TypeProperty.DataType(childComplexity), true + + case "TypeProperty.name": + if e.complexity.TypeProperty.Name == nil { + break + } + + return e.complexity.TypeProperty.Name(childComplexity), true + + case "TypeProperty.typeId": + if e.complexity.TypeProperty.TypeID == nil { + break + } + + return e.complexity.TypeProperty.TypeID(childComplexity), true + + } + return 0, false +} + +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + rc := graphql.GetOperationContext(ctx) + ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap( + ec.unmarshalInputInstanceFilter, + ec.unmarshalInputTypeFilter, + ) + first := true + + switch rc.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, rc.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response + } + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) + } +} + +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult +} + +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), + } + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null + } + ec.deferredResults <- ds + }() +} + +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapSchema(parsedSchema), nil +} + +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") + } + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil +} + +var sources = []*ast.Source{ + {Name: "../../api/graphql/schema.graphqls", Input: `type Artifact { + id: ID + typeId: ID! + uri: String! + state: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ArtifactType! + properties : [ArtifactProperty!] +} + +type ArtifactProperty { + artifactId: ID + name: String + isCustomProperty: Boolean! + propertyValue: Value! +} + +type Context { + id: ID + typeId: ID! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ContextType! + parent: Context + children: [Context] + attributions: [Artifact!] + associations: [Execution!] + properties: [ContextProperty!] +} + +type ContextProperty { + contextId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +type Event { + id: ID + artifactId: ID! + executionId: ID! + type: Int! + artifact: Artifact + execution: Execution + millisecondsSinceEpoch: Int! +} + +type EventPath { + eventId: ID! + isIndexStep: Int! + stepIndex: Int! + stepKey: String! +} + +type Execution { + id: ID + typeId: ID! + lastKnownState: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ExecutionType! + properties: [ExecutionProperty!] +} + +type ExecutionProperty { + executionId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +union Value = IntValue | DoubleValue | StringValue | BoolValue + +type IntValue { + value: Int! +} + +type DoubleValue { + value: Float! +} + +type StringValue { + value: String! +} + +type BoolValue { + value: Boolean! +} + +interface Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type TypeProperty { + typeId: ID! + name: String! + dataType: Int! +} + +type ArtifactType implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ContextType implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ExecutionType implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +input TypeFilter { + ids: [ID!] + names: [String!] + versions: [String!] + externalIds: [String!] +} + +input InstanceFilter { + ids: [ID!] + typeIds: [ID!] + names: [String!] + externalIds: [String!] +} + +type Query { + types(filter: TypeFilter): [Type!] + artifactTypes(filter: TypeFilter): [ArtifactType!] + contextTypes(filter: TypeFilter): [ContextType!] + executionTypes(filter: TypeFilter): [ExecutionType!] + artifacts(filter: InstanceFilter): [Artifact!] + contexts(filter: InstanceFilter): [Context!] + executions(filter: InstanceFilter): [Execution!] + events: [Event!] +} +`, BuiltIn: false}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["name"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["name"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_artifactTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_artifacts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_contextTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_contexts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_executionTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_executions_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_types_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := rawArgs["includeDeprecated"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["includeDeprecated"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := rawArgs["includeDeprecated"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["includeDeprecated"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Artifact_id(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_typeId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_uri(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_uri(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.URI, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_uri(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_state(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_state(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.State, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_state(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_name(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastUpdateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_type(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Artifact().Type(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*graph.ArtifactType) + fc.Result = res + return ec.marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ArtifactType_id(ctx, field) + case "name": + return ec.fieldContext_ArtifactType_name(ctx, field) + case "version": + return ec.fieldContext_ArtifactType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ArtifactType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ArtifactType_description(ctx, field) + case "externalId": + return ec.fieldContext_ArtifactType_externalId(ctx, field) + case "properties": + return ec.fieldContext_ArtifactType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ArtifactType", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ArtifactProperty) + fc.Result = res + return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "artifactId": + return ec.fieldContext_ArtifactProperty_artifactId(ctx, field) + case "name": + return ec.fieldContext_ArtifactProperty_name(ctx, field) + case "isCustomProperty": + return ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) + case "propertyValue": + return ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ArtifactProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_artifactId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ArtifactID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsCustomProperty, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PropertyValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(graph.Value) + fc.Result = res + return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Value does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _BoolValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.BoolValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_BoolValue_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_BoolValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "BoolValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_id(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_typeId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_name(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastUpdateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_type(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*graph.ContextType) + fc.Result = res + return ec.marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ContextType_id(ctx, field) + case "name": + return ec.fieldContext_ContextType_name(ctx, field) + case "version": + return ec.fieldContext_ContextType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ContextType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ContextType_description(ctx, field) + case "externalId": + return ec.fieldContext_ContextType_externalId(ctx, field) + case "properties": + return ec.fieldContext_ContextType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ContextType", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_parent(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_parent(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Parent, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graph.Context) + fc.Result = res + return ec.marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Context_id(ctx, field) + case "typeId": + return ec.fieldContext_Context_typeId(ctx, field) + case "name": + return ec.fieldContext_Context_name(ctx, field) + case "externalId": + return ec.fieldContext_Context_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Context_type(ctx, field) + case "parent": + return ec.fieldContext_Context_parent(ctx, field) + case "children": + return ec.fieldContext_Context_children(ctx, field) + case "attributions": + return ec.fieldContext_Context_attributions(ctx, field) + case "associations": + return ec.fieldContext_Context_associations(ctx, field) + case "properties": + return ec.fieldContext_Context_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_children(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_children(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Children, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Context) + fc.Result = res + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_children(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Context_id(ctx, field) + case "typeId": + return ec.fieldContext_Context_typeId(ctx, field) + case "name": + return ec.fieldContext_Context_name(ctx, field) + case "externalId": + return ec.fieldContext_Context_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Context_type(ctx, field) + case "parent": + return ec.fieldContext_Context_parent(ctx, field) + case "children": + return ec.fieldContext_Context_children(ctx, field) + case "attributions": + return ec.fieldContext_Context_attributions(ctx, field) + case "associations": + return ec.fieldContext_Context_associations(ctx, field) + case "properties": + return ec.fieldContext_Context_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_attributions(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_attributions(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Attributions, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Artifact) + fc.Result = res + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_attributions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Artifact_id(ctx, field) + case "typeId": + return ec.fieldContext_Artifact_typeId(ctx, field) + case "uri": + return ec.fieldContext_Artifact_uri(ctx, field) + case "state": + return ec.fieldContext_Artifact_state(ctx, field) + case "name": + return ec.fieldContext_Artifact_name(ctx, field) + case "externalId": + return ec.fieldContext_Artifact_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Artifact_type(ctx, field) + case "properties": + return ec.fieldContext_Artifact_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_associations(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_associations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Associations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Execution) + fc.Result = res + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_associations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Execution_id(ctx, field) + case "typeId": + return ec.fieldContext_Execution_typeId(ctx, field) + case "lastKnownState": + return ec.fieldContext_Execution_lastKnownState(ctx, field) + case "name": + return ec.fieldContext_Execution_name(ctx, field) + case "externalId": + return ec.fieldContext_Execution_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Execution_type(ctx, field) + case "properties": + return ec.fieldContext_Execution_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ContextProperty) + fc.Result = res + return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "contextId": + return ec.fieldContext_ContextProperty_contextId(ctx, field) + case "name": + return ec.fieldContext_ContextProperty_name(ctx, field) + case "isCustomProperty": + return ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) + case "propertyValue": + return ec.fieldContext_ContextProperty_propertyValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ContextProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_contextId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_contextId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ContextID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_contextId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsCustomProperty, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_propertyValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PropertyValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(graph.Value) + fc.Result = res + return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Value does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _DoubleValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.DoubleValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DoubleValue_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DoubleValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DoubleValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_id(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_artifactId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ArtifactID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_executionId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExecutionID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_type(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_artifact(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Artifact, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graph.Artifact) + fc.Result = res + return ec.marshalOArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_artifact(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Artifact_id(ctx, field) + case "typeId": + return ec.fieldContext_Artifact_typeId(ctx, field) + case "uri": + return ec.fieldContext_Artifact_uri(ctx, field) + case "state": + return ec.fieldContext_Artifact_state(ctx, field) + case "name": + return ec.fieldContext_Artifact_name(ctx, field) + case "externalId": + return ec.fieldContext_Artifact_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Artifact_type(ctx, field) + case "properties": + return ec.fieldContext_Artifact_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_execution(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_execution(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Execution, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graph.Execution) + fc.Result = res + return ec.marshalOExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_execution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Execution_id(ctx, field) + case "typeId": + return ec.fieldContext_Execution_typeId(ctx, field) + case "lastKnownState": + return ec.fieldContext_Execution_lastKnownState(ctx, field) + case "name": + return ec.fieldContext_Execution_name(ctx, field) + case "externalId": + return ec.fieldContext_Execution_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Execution_type(ctx, field) + case "properties": + return ec.fieldContext_Execution_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.MillisecondsSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_eventId(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_eventId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.EventID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_eventId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_isIndexStep(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsIndexStep, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_stepIndex(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_stepIndex(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.StepIndex, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_stepIndex(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_stepKey(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_stepKey(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.StepKey, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_stepKey(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_id(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_typeId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_lastKnownState(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_lastKnownState(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastKnownState, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_lastKnownState(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_name(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastUpdateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*graph.ExecutionType) + fc.Result = res + return ec.marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ExecutionType_id(ctx, field) + case "name": + return ec.fieldContext_ExecutionType_name(ctx, field) + case "version": + return ec.fieldContext_ExecutionType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ExecutionType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ExecutionType_description(ctx, field) + case "externalId": + return ec.fieldContext_ExecutionType_externalId(ctx, field) + case "inputType": + return ec.fieldContext_ExecutionType_inputType(ctx, field) + case "outputType": + return ec.fieldContext_ExecutionType_outputType(ctx, field) + case "properties": + return ec.fieldContext_ExecutionType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ExecutionType", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ExecutionProperty) + fc.Result = res + return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "executionId": + return ec.fieldContext_ExecutionProperty_executionId(ctx, field) + case "name": + return ec.fieldContext_ExecutionProperty_name(ctx, field) + case "isCustomProperty": + return ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) + case "propertyValue": + return ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ExecutionProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_executionId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExecutionID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsCustomProperty, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PropertyValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(graph.Value) + fc.Result = res + return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Value does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_inputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_outputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.OutputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _IntValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.IntValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_IntValue_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_IntValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "IntValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Query_types(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Types(rctx, fc.Args["filter"].(*graph.TypeFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]graph.Type) + fc.Result = res + return ec.marshalOType2ᚕgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_types_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_artifactTypes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_artifactTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ArtifactTypes(rctx, fc.Args["filter"].(*graph.TypeFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ArtifactType) + fc.Result = res + return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_artifactTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ArtifactType_id(ctx, field) + case "name": + return ec.fieldContext_ArtifactType_name(ctx, field) + case "version": + return ec.fieldContext_ArtifactType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ArtifactType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ArtifactType_description(ctx, field) + case "externalId": + return ec.fieldContext_ArtifactType_externalId(ctx, field) + case "properties": + return ec.fieldContext_ArtifactType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ArtifactType", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_artifactTypes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_contextTypes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_contextTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ContextTypes(rctx, fc.Args["filter"].(*graph.TypeFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ContextType) + fc.Result = res + return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_contextTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ContextType_id(ctx, field) + case "name": + return ec.fieldContext_ContextType_name(ctx, field) + case "version": + return ec.fieldContext_ContextType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ContextType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ContextType_description(ctx, field) + case "externalId": + return ec.fieldContext_ContextType_externalId(ctx, field) + case "properties": + return ec.fieldContext_ContextType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ContextType", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_contextTypes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_executionTypes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_executionTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().ExecutionTypes(rctx, fc.Args["filter"].(*graph.TypeFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ExecutionType) + fc.Result = res + return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_executionTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ExecutionType_id(ctx, field) + case "name": + return ec.fieldContext_ExecutionType_name(ctx, field) + case "version": + return ec.fieldContext_ExecutionType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ExecutionType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ExecutionType_description(ctx, field) + case "externalId": + return ec.fieldContext_ExecutionType_externalId(ctx, field) + case "inputType": + return ec.fieldContext_ExecutionType_inputType(ctx, field) + case "outputType": + return ec.fieldContext_ExecutionType_outputType(ctx, field) + case "properties": + return ec.fieldContext_ExecutionType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ExecutionType", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_executionTypes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_artifacts(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_artifacts(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Artifacts(rctx, fc.Args["filter"].(*graph.InstanceFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Artifact) + fc.Result = res + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_artifacts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Artifact_id(ctx, field) + case "typeId": + return ec.fieldContext_Artifact_typeId(ctx, field) + case "uri": + return ec.fieldContext_Artifact_uri(ctx, field) + case "state": + return ec.fieldContext_Artifact_state(ctx, field) + case "name": + return ec.fieldContext_Artifact_name(ctx, field) + case "externalId": + return ec.fieldContext_Artifact_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Artifact_type(ctx, field) + case "properties": + return ec.fieldContext_Artifact_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_artifacts_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_contexts(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_contexts(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Contexts(rctx, fc.Args["filter"].(*graph.InstanceFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Context) + fc.Result = res + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_contexts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Context_id(ctx, field) + case "typeId": + return ec.fieldContext_Context_typeId(ctx, field) + case "name": + return ec.fieldContext_Context_name(ctx, field) + case "externalId": + return ec.fieldContext_Context_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Context_type(ctx, field) + case "parent": + return ec.fieldContext_Context_parent(ctx, field) + case "children": + return ec.fieldContext_Context_children(ctx, field) + case "attributions": + return ec.fieldContext_Context_attributions(ctx, field) + case "associations": + return ec.fieldContext_Context_associations(ctx, field) + case "properties": + return ec.fieldContext_Context_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_contexts_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_executions(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_executions(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Executions(rctx, fc.Args["filter"].(*graph.InstanceFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Execution) + fc.Result = res + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_executions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Execution_id(ctx, field) + case "typeId": + return ec.fieldContext_Execution_typeId(ctx, field) + case "lastKnownState": + return ec.fieldContext_Execution_lastKnownState(ctx, field) + case "name": + return ec.fieldContext_Execution_name(ctx, field) + case "externalId": + return ec.fieldContext_Execution_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Execution_type(ctx, field) + case "properties": + return ec.fieldContext_Execution_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_executions_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_events(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_events(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Events(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Event) + fc.Result = res + return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Event_id(ctx, field) + case "artifactId": + return ec.fieldContext_Event_artifactId(ctx, field) + case "executionId": + return ec.fieldContext_Event_executionId(ctx, field) + case "type": + return ec.fieldContext_Event_type(ctx, field) + case "artifact": + return ec.fieldContext_Event_artifact(ctx, field) + case "execution": + return ec.fieldContext_Event_execution(ctx, field) + case "millisecondsSinceEpoch": + return ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Event", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectType(fc.Args["name"].(string)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query___schema(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.introspectSchema() + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + fc.Result = res + return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query___schema(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "description": + return ec.fieldContext___Schema_description(ctx, field) + case "types": + return ec.fieldContext___Schema_types(ctx, field) + case "queryType": + return ec.fieldContext___Schema_queryType(ctx, field) + case "mutationType": + return ec.fieldContext___Schema_mutationType(ctx, field) + case "subscriptionType": + return ec.fieldContext___Schema_subscriptionType(ctx, field) + case "directives": + return ec.fieldContext___Schema_directives(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _StringValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.StringValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_StringValue_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_StringValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "StringValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _TypeProperty_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.TypeProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TypeProperty_typeId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_TypeProperty_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TypeProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _TypeProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.TypeProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TypeProperty_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_TypeProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TypeProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _TypeProperty_dataType(ctx context.Context, field graphql.CollectedField, obj *graph.TypeProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_TypeProperty_dataType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DataType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_TypeProperty_dataType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TypeProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_locations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Locations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]string) + fc.Result = res + return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_locations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __DirectiveLocation does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsRepeatable, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Directive", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__EnumValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_args(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Args, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsDeprecated(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DeprecationReason(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Field_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Field", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.DefaultValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__InputValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_types(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Types(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_queryType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.QueryType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_queryType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_mutationType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.MutationType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_mutationType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.SubscriptionType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Schema_directives(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Directives(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.([]introspection.Directive) + fc.Result = res + return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Schema_directives(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Schema", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Directive_name(ctx, field) + case "description": + return ec.fieldContext___Directive_description(ctx, field) + case "locations": + return ec.fieldContext___Directive_locations(ctx, field) + case "args": + return ec.fieldContext___Directive_args(ctx, field) + case "isRepeatable": + return ec.fieldContext___Directive_isRepeatable(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_kind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Kind(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalN__TypeKind2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_kind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type __TypeKind does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Type_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PossibleTypes(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + fc.Result = res + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Type_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputFields(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + fc.Result = res + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___InputValue_name(ctx, field) + case "description": + return ec.fieldContext___InputValue_description(ctx, field) + case "type": + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.OfType(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputInstanceFilter(ctx context.Context, obj interface{}) (graph.InstanceFilter, error) { + var it graph.InstanceFilter + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"ids", "typeIds", "names", "externalIds"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "ids": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) + data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Ids = data + case "typeIds": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("typeIds")) + data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.TypeIds = data + case "names": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Names = data + case "externalIds": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.ExternalIds = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputTypeFilter(ctx context.Context, obj interface{}) (graph.TypeFilter, error) { + var it graph.TypeFilter + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"ids", "names", "versions", "externalIds"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "ids": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) + data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Ids = data + case "names": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Names = data + case "versions": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("versions")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Versions = data + case "externalIds": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.ExternalIds = data + } + } + + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) _Type(ctx context.Context, sel ast.SelectionSet, obj graph.Type) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case graph.ArtifactType: + return ec._ArtifactType(ctx, sel, &obj) + case *graph.ArtifactType: + if obj == nil { + return graphql.Null + } + return ec._ArtifactType(ctx, sel, obj) + case graph.ContextType: + return ec._ContextType(ctx, sel, &obj) + case *graph.ContextType: + if obj == nil { + return graphql.Null + } + return ec._ContextType(ctx, sel, obj) + case graph.ExecutionType: + return ec._ExecutionType(ctx, sel, &obj) + case *graph.ExecutionType: + if obj == nil { + return graphql.Null + } + return ec._ExecutionType(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +func (ec *executionContext) _Value(ctx context.Context, sel ast.SelectionSet, obj graph.Value) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case graph.IntValue: + return ec._IntValue(ctx, sel, &obj) + case *graph.IntValue: + if obj == nil { + return graphql.Null + } + return ec._IntValue(ctx, sel, obj) + case graph.DoubleValue: + return ec._DoubleValue(ctx, sel, &obj) + case *graph.DoubleValue: + if obj == nil { + return graphql.Null + } + return ec._DoubleValue(ctx, sel, obj) + case graph.StringValue: + return ec._StringValue(ctx, sel, &obj) + case *graph.StringValue: + if obj == nil { + return graphql.Null + } + return ec._StringValue(ctx, sel, obj) + case graph.BoolValue: + return ec._BoolValue(ctx, sel, &obj) + case *graph.BoolValue: + if obj == nil { + return graphql.Null + } + return ec._BoolValue(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) + } +} + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var artifactImplementors = []string{"Artifact"} + +func (ec *executionContext) _Artifact(ctx context.Context, sel ast.SelectionSet, obj *graph.Artifact) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, artifactImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Artifact") + case "id": + out.Values[i] = ec._Artifact_id(ctx, field, obj) + case "typeId": + out.Values[i] = ec._Artifact_typeId(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "uri": + out.Values[i] = ec._Artifact_uri(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "state": + out.Values[i] = ec._Artifact_state(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "name": + out.Values[i] = ec._Artifact_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "externalId": + out.Values[i] = ec._Artifact_externalId(ctx, field, obj) + case "createTimeSinceEpoch": + out.Values[i] = ec._Artifact_createTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "lastUpdateTimeSinceEpoch": + out.Values[i] = ec._Artifact_lastUpdateTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "type": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Artifact_type(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "properties": + out.Values[i] = ec._Artifact_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var artifactPropertyImplementors = []string{"ArtifactProperty"} + +func (ec *executionContext) _ArtifactProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactProperty) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, artifactPropertyImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ArtifactProperty") + case "artifactId": + out.Values[i] = ec._ArtifactProperty_artifactId(ctx, field, obj) + case "name": + out.Values[i] = ec._ArtifactProperty_name(ctx, field, obj) + case "isCustomProperty": + out.Values[i] = ec._ArtifactProperty_isCustomProperty(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "propertyValue": + out.Values[i] = ec._ArtifactProperty_propertyValue(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var artifactTypeImplementors = []string{"ArtifactType", "Type"} + +func (ec *executionContext) _ArtifactType(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactType) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, artifactTypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ArtifactType") + case "id": + out.Values[i] = ec._ArtifactType_id(ctx, field, obj) + case "name": + out.Values[i] = ec._ArtifactType_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "version": + out.Values[i] = ec._ArtifactType_version(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "typeKind": + out.Values[i] = ec._ArtifactType_typeKind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._ArtifactType_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._ArtifactType_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._ArtifactType_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var boolValueImplementors = []string{"BoolValue", "Value"} + +func (ec *executionContext) _BoolValue(ctx context.Context, sel ast.SelectionSet, obj *graph.BoolValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, boolValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("BoolValue") + case "value": + out.Values[i] = ec._BoolValue_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var contextImplementors = []string{"Context"} + +func (ec *executionContext) _Context(ctx context.Context, sel ast.SelectionSet, obj *graph.Context) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, contextImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Context") + case "id": + out.Values[i] = ec._Context_id(ctx, field, obj) + case "typeId": + out.Values[i] = ec._Context_typeId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Context_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._Context_externalId(ctx, field, obj) + case "createTimeSinceEpoch": + out.Values[i] = ec._Context_createTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "lastUpdateTimeSinceEpoch": + out.Values[i] = ec._Context_lastUpdateTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec._Context_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "parent": + out.Values[i] = ec._Context_parent(ctx, field, obj) + case "children": + out.Values[i] = ec._Context_children(ctx, field, obj) + case "attributions": + out.Values[i] = ec._Context_attributions(ctx, field, obj) + case "associations": + out.Values[i] = ec._Context_associations(ctx, field, obj) + case "properties": + out.Values[i] = ec._Context_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var contextPropertyImplementors = []string{"ContextProperty"} + +func (ec *executionContext) _ContextProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextProperty) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, contextPropertyImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ContextProperty") + case "contextId": + out.Values[i] = ec._ContextProperty_contextId(ctx, field, obj) + case "name": + out.Values[i] = ec._ContextProperty_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isCustomProperty": + out.Values[i] = ec._ContextProperty_isCustomProperty(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "propertyValue": + out.Values[i] = ec._ContextProperty_propertyValue(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var contextTypeImplementors = []string{"ContextType", "Type"} + +func (ec *executionContext) _ContextType(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextType) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, contextTypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ContextType") + case "id": + out.Values[i] = ec._ContextType_id(ctx, field, obj) + case "name": + out.Values[i] = ec._ContextType_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "version": + out.Values[i] = ec._ContextType_version(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "typeKind": + out.Values[i] = ec._ContextType_typeKind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._ContextType_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._ContextType_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._ContextType_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var doubleValueImplementors = []string{"DoubleValue", "Value"} + +func (ec *executionContext) _DoubleValue(ctx context.Context, sel ast.SelectionSet, obj *graph.DoubleValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, doubleValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DoubleValue") + case "value": + out.Values[i] = ec._DoubleValue_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var eventImplementors = []string{"Event"} + +func (ec *executionContext) _Event(ctx context.Context, sel ast.SelectionSet, obj *graph.Event) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, eventImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Event") + case "id": + out.Values[i] = ec._Event_id(ctx, field, obj) + case "artifactId": + out.Values[i] = ec._Event_artifactId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "executionId": + out.Values[i] = ec._Event_executionId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec._Event_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "artifact": + out.Values[i] = ec._Event_artifact(ctx, field, obj) + case "execution": + out.Values[i] = ec._Event_execution(ctx, field, obj) + case "millisecondsSinceEpoch": + out.Values[i] = ec._Event_millisecondsSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var eventPathImplementors = []string{"EventPath"} + +func (ec *executionContext) _EventPath(ctx context.Context, sel ast.SelectionSet, obj *graph.EventPath) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, eventPathImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("EventPath") + case "eventId": + out.Values[i] = ec._EventPath_eventId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isIndexStep": + out.Values[i] = ec._EventPath_isIndexStep(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "stepIndex": + out.Values[i] = ec._EventPath_stepIndex(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "stepKey": + out.Values[i] = ec._EventPath_stepKey(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var executionImplementors = []string{"Execution"} + +func (ec *executionContext) _Execution(ctx context.Context, sel ast.SelectionSet, obj *graph.Execution) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, executionImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Execution") + case "id": + out.Values[i] = ec._Execution_id(ctx, field, obj) + case "typeId": + out.Values[i] = ec._Execution_typeId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "lastKnownState": + out.Values[i] = ec._Execution_lastKnownState(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Execution_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._Execution_externalId(ctx, field, obj) + case "createTimeSinceEpoch": + out.Values[i] = ec._Execution_createTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "lastUpdateTimeSinceEpoch": + out.Values[i] = ec._Execution_lastUpdateTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec._Execution_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "properties": + out.Values[i] = ec._Execution_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var executionPropertyImplementors = []string{"ExecutionProperty"} + +func (ec *executionContext) _ExecutionProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionProperty) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, executionPropertyImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ExecutionProperty") + case "executionId": + out.Values[i] = ec._ExecutionProperty_executionId(ctx, field, obj) + case "name": + out.Values[i] = ec._ExecutionProperty_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isCustomProperty": + out.Values[i] = ec._ExecutionProperty_isCustomProperty(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "propertyValue": + out.Values[i] = ec._ExecutionProperty_propertyValue(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var executionTypeImplementors = []string{"ExecutionType", "Type"} + +func (ec *executionContext) _ExecutionType(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionType) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, executionTypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ExecutionType") + case "id": + out.Values[i] = ec._ExecutionType_id(ctx, field, obj) + case "name": + out.Values[i] = ec._ExecutionType_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "version": + out.Values[i] = ec._ExecutionType_version(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "typeKind": + out.Values[i] = ec._ExecutionType_typeKind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._ExecutionType_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._ExecutionType_externalId(ctx, field, obj) + case "inputType": + out.Values[i] = ec._ExecutionType_inputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "outputType": + out.Values[i] = ec._ExecutionType_outputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "properties": + out.Values[i] = ec._ExecutionType_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var intValueImplementors = []string{"IntValue", "Value"} + +func (ec *executionContext) _IntValue(ctx context.Context, sel ast.SelectionSet, obj *graph.IntValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, intValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("IntValue") + case "value": + out.Values[i] = ec._IntValue_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var queryImplementors = []string{"Query"} + +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) + ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ + Object: "Query", + }) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ + Object: field.Name, + Field: field, + }) + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "types": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_types(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "artifactTypes": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_artifactTypes(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "contextTypes": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_contextTypes(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "executionTypes": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_executionTypes(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "artifacts": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_artifacts(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "contexts": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_contexts(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "executions": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_executions(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "events": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_events(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "__type": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___type(ctx, field) + }) + case "__schema": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Query___schema(ctx, field) + }) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var stringValueImplementors = []string{"StringValue", "Value"} + +func (ec *executionContext) _StringValue(ctx context.Context, sel ast.SelectionSet, obj *graph.StringValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, stringValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("StringValue") + case "value": + out.Values[i] = ec._StringValue_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var typePropertyImplementors = []string{"TypeProperty"} + +func (ec *executionContext) _TypeProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.TypeProperty) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, typePropertyImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("TypeProperty") + case "typeId": + out.Values[i] = ec._TypeProperty_typeId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._TypeProperty_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "dataType": + out.Values[i] = ec._TypeProperty_dataType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __DirectiveImplementors = []string{"__Directive"} + +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "args": + out.Values[i] = ec.___Directive_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isRepeatable": + out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __FieldImplementors = []string{"__Field"} + +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __InputValueImplementors = []string{"__InputValue"} + +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __SchemaImplementors = []string{"__Schema"} + +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "description": + out.Values[i] = ec.___Schema_description(ctx, field, obj) + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var __TypeImplementors = []string{"__Type"} + +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + case "specifiedByURL": + out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +// endregion **************************** object.gotpl **************************** + +// region ***************************** type.gotpl ***************************** + +func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Artifact(ctx, sel, v) +} + +func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ArtifactProperty(ctx, sel, v) +} + +func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { + return ec._ArtifactType(ctx, sel, &v) +} + +func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ArtifactType(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v interface{}) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + res := graphql.MarshalBoolean(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Context(ctx, sel, v) +} + +func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ContextProperty(ctx, sel, v) +} + +func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ContextType(ctx, sel, v) +} + +func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Event(ctx, sel, v) +} + +func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Execution(ctx, sel, v) +} + +func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ExecutionProperty(ctx, sel, v) +} + +func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._ExecutionType(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { + res, err := graphql.UnmarshalFloatContext(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { + res := graphql.MarshalFloatContext(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return graphql.WrapContextMarshaler(ctx, res) +} + +func (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalID(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalID(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) { + res, err := graphql.UnmarshalInt(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + res := graphql.MarshalInt(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalNType2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Type(ctx, sel, v) +} + +func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._TypeProperty(ctx, sel, v) +} + +func (ec *executionContext) marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._Value(ctx, sel, v) +} + +func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { + return ec.___Directive(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { + return ec.___EnumValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { + return ec.___Field(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { + return ec.___InputValue(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v introspection.Type) graphql.Marshaler { + return ec.___Type(ctx, sel, &v) +} + +func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v interface{}) (string, error) { + res, err := graphql.UnmarshalString(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { + res := graphql.MarshalString(v) + if res == graphql.Null { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + } + return res +} + +func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Artifact(ctx, sel, v) +} + +func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) { + res, err := graphql.UnmarshalBoolean(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { + res := graphql.MarshalBoolean(v) + return res +} + +func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalBoolean(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { + if v == nil { + return graphql.Null + } + res := graphql.MarshalBoolean(*v) + return res +} + +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + return ret +} + +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Context(ctx, sel, v) +} + +func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._Execution(ctx, sel, v) +} + +func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOID2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNID2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOID2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNID2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOID2ᚖstring(ctx context.Context, v interface{}) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalID(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOID2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + res := graphql.MarshalID(*v) + return res +} + +func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputInstanceFilter(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { + if v == nil { + return nil, nil + } + var vSlice []interface{} + if v != nil { + vSlice = graphql.CoerceList(v) + } + var err error + res := make([]string, len(vSlice)) + for i := range vSlice { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) + res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) + if err != nil { + return nil, err + } + } + return res, nil +} + +func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + for i := range v { + ret[i] = ec.marshalNString2string(ctx, sel, v[i]) + } + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { + if v == nil { + return nil, nil + } + res, err := graphql.UnmarshalString(v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { + if v == nil { + return graphql.Null + } + res := graphql.MarshalString(*v) + return res +} + +func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNType2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { + if v == nil { + return nil, nil + } + res, err := ec.unmarshalInputTypeFilter(ctx, v) + return &res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx context.Context, sel ast.SelectionSet, v *introspection.Schema) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.___Schema(ctx, sel, v) +} + +func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + +func (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec.___Type(ctx, sel, v) +} + +// endregion ***************************** type.gotpl ***************************** diff --git a/server/graph/resolver.go b/server/graph/resolver.go new file mode 100644 index 00000000..a25c09c6 --- /dev/null +++ b/server/graph/resolver.go @@ -0,0 +1,7 @@ +package graph + +// This file will not be regenerated automatically. +// +// It serves as dependency injection for your app, add any dependencies you require here. + +type Resolver struct{} diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go new file mode 100644 index 00000000..2955bfb8 --- /dev/null +++ b/server/graph/schema.resolvers.go @@ -0,0 +1,70 @@ +package graph + +// This file will be automatically regenerated based on the schema, any resolver implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen version v0.17.36 + +import ( + "context" + "fmt" + + "github.com/dhirajsb/ml-metadata-go-server/model/graph" +) + +// Type is the resolver for the type field. +func (r *artifactResolver) Type(ctx context.Context, obj *graph.Artifact) (*graph.ArtifactType, error) { + id := "1" + return &graph.ArtifactType{ID: &id, Name: "TestType"}, nil +} + +// Types is the resolver for the types field. +func (r *queryResolver) Types(ctx context.Context, filter *graph.TypeFilter) ([]graph.Type, error) { + //panic(fmt.Errorf("not implemented: Types - types")) + id := "1" + return []graph.Type{graph.ArtifactType{ID: &id, Name: "TestType"}}, nil +} + +// ArtifactTypes is the resolver for the artifactTypes field. +func (r *queryResolver) ArtifactTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ArtifactType, error) { + panic(fmt.Errorf("not implemented: ArtifactTypes - artifactTypes")) +} + +// ContextTypes is the resolver for the contextTypes field. +func (r *queryResolver) ContextTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ContextType, error) { + panic(fmt.Errorf("not implemented: ContextTypes - contextTypes")) +} + +// ExecutionTypes is the resolver for the executionTypes field. +func (r *queryResolver) ExecutionTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ExecutionType, error) { + panic(fmt.Errorf("not implemented: ExecutionTypes - executionTypes")) +} + +// Artifacts is the resolver for the artifacts field. +func (r *queryResolver) Artifacts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Artifact, error) { + id := "1" + return []*graph.Artifact{{ID: &id, Name: "TestArtifact", TypeID: id}}, nil +} + +// Contexts is the resolver for the contexts field. +func (r *queryResolver) Contexts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Context, error) { + panic(fmt.Errorf("not implemented: Contexts - contexts")) +} + +// Executions is the resolver for the executions field. +func (r *queryResolver) Executions(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Execution, error) { + panic(fmt.Errorf("not implemented: Executions - executions")) +} + +// Events is the resolver for the events field. +func (r *queryResolver) Events(ctx context.Context) ([]*graph.Event, error) { + panic(fmt.Errorf("not implemented: Events - events")) +} + +// Artifact returns ArtifactResolver implementation. +func (r *Resolver) Artifact() ArtifactResolver { return &artifactResolver{r} } + +// Query returns QueryResolver implementation. +func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } + +type artifactResolver struct{ *Resolver } +type queryResolver struct{ *Resolver } diff --git a/tools.go b/tools.go new file mode 100644 index 00000000..4f04ccd8 --- /dev/null +++ b/tools.go @@ -0,0 +1,9 @@ +//go:build tools +// +build tools + +package tools + +import ( + _ "github.com/99designs/gqlgen" + _ "github.com/99designs/gqlgen/graphql/introspection" +) From a5603d8a64fb5a55fac08d11a47fee141f997005 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Mon, 4 Sep 2023 23:36:45 -0700 Subject: [PATCH 018/254] Initial README.md --- README.md | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0cc85439..e263523a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,46 @@ # ml-metadata-go-server +A go based server that implements a gRPC interface for [ml_metadata](https://github.com/google/ml-metadata/) library. +It adds other features on top of the functionality offered by the gRPC interface. +## Pre-requisites: +- go +- protoc +- python 3.9 +## Building +Run the following command to build the server binary: +``` +make build +``` +The generated binary uses spf13 cmdline args. More information on using the server can be obtained by running the command: +``` +./ml-metadata-go-server --help +``` +## Creating/Migrating Server DB +The server uses a local SQLite DB file (`metadata.sqlite.db` by default), which can be configured using the `-d` cmdline option. +The following command creates the DB: +``` +./ml-metadata-go-server migrate +``` +### Loading metadata library +Run the following command to load a metadata library: +``` +./ml-metadata-go-server migrate -m config/metadata-library +``` +Note that currently no duplicate detection is done as the implementation is a WIP proof of concept. +Running this command multiple times will create duplicate metadata types. +To clear the DB simply delete the SQLite DB file `metadata.sqlite.db`. -A simple go server that implements a gRPC interface for [ml_metadata](https://github.com/google/ml-metadata/) library. +### Running Server +Run the following command to start the server: +``` +make run/server & +``` +### Running Python ml-metadata test client +Run the following command to run the ml-metadata Python test client: +``` +make run/client +``` +### Clean +Run the following command to clean the DB file, generated gRPC and GraphQL models, etc.: +``` +make clean +``` \ No newline at end of file From 1bdf8acfee84da1a863b42131a79d951fe849a4c Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 5 Sep 2023 08:51:33 -0700 Subject: [PATCH 019/254] Added GraphQL playground to readme --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index e263523a..9d7733fb 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,13 @@ Run the following command to run the ml-metadata Python test client: ``` make run/client ``` +### Running GraphQL Playground +This project includes support for a GraphiQL playground, which supports interactive query design. +It can be reached by opening the following URL in a web browser: +``` +http://localhost:8080/ +``` +Where, 8080 is the default port that the server listens on. This port can be changed with the `-p` option. ### Clean Run the following command to clean the DB file, generated gRPC and GraphQL models, etc.: ``` From ddb9583d62041d79a7389a316ce17359bb984192 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 5 Sep 2023 13:16:51 -0700 Subject: [PATCH 020/254] Updated pre-requisites in readme, minor updates to Makefile --- Makefile | 6 +++++- README.md | 9 +++++++-- go.mod | 1 + go.sum | 2 ++ tools.go | 2 ++ 5 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 7efba1ef..117659ce 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,10 @@ gen/graph: model/graph/models_gen.go model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml go run github.com/99designs/gqlgen generate +.PHONY: vet +vet: + go vet ./... + .PHONY: clean clean: rm -Rf ./ml-metadata-go-server ml_metadata/proto/*.go ./model/graph/*.go @@ -22,7 +26,7 @@ vendor: go mod vendor .PHONY: build -build: gen +build: gen vet go build .PHONY: gen diff --git a/README.md b/README.md index 9d7733fb..b69f5f7e 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,13 @@ A go based server that implements a gRPC interface for [ml_metadata](https://github.com/google/ml-metadata/) library. It adds other features on top of the functionality offered by the gRPC interface. ## Pre-requisites: -- go -- protoc +- go >= 1.19 +- protoc - [Protocol buffer compiler](https://grpc.io/docs/protoc-installation/). +- gRPC go plugins - Installed with the following commands: +``` +go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest +``` - python 3.9 ## Building Run the following command to build the server binary: diff --git a/go.mod b/go.mod index 670d6190..9921cf97 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/vektah/gqlparser/v2 v2.5.8 golang.org/x/sync v0.2.0 google.golang.org/grpc v1.57.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/sqlite v1.5.3 diff --git a/go.sum b/go.sum index 3c29015f..6dc5c69d 100644 --- a/go.sum +++ b/go.sum @@ -508,6 +508,8 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/tools.go b/tools.go index 4f04ccd8..ad5606e8 100644 --- a/tools.go +++ b/tools.go @@ -4,6 +4,8 @@ package tools import ( + _ "google.golang.org/protobuf/cmd/protoc-gen-go" + _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" _ "github.com/99designs/gqlgen" _ "github.com/99designs/gqlgen/graphql/introspection" ) From d9d7d771b88fafb4d4ff46bc0267d5b10d989ebf Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 5 Sep 2023 17:44:20 -0700 Subject: [PATCH 021/254] cmux java client grpc fix --- cmd/serve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/serve.go b/cmd/serve.go index f19417d7..9102ecc9 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -98,8 +98,8 @@ func runServer(cmd *cobra.Command, args []string) error { log.Fatalf("server listen failed: %v", err) } m := cmux.New(listener) - grpcListener := m.Match(cmux.HTTP2HeaderField("content-type", "application/grpc")) gqlListener := m.Match(cmux.HTTP1Fast()) + grpcListener := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) // gRPC server grpcServer := grpcListenerServer(grpcListener, server.NewGrpcServer(db)) From 06a2a08769dcf09f7d8c50a4d17d2d1de5930338 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 5 Sep 2023 18:26:18 -0700 Subject: [PATCH 022/254] Fixed python client command and lib dependencies in readme --- Makefile | 2 +- README.md | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 117659ce..efede0f9 100644 --- a/Makefile +++ b/Makefile @@ -42,7 +42,7 @@ run/server: gen .PHONY: run/client run/client: gen - python3.9 test/python/test_mlmetadata.py + python test/python/test_mlmetadata.py .PHONY: serve serve: build diff --git a/README.md b/README.md index b69f5f7e..1d3dba1b 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,11 @@ Run the following command to start the server: make run/server & ``` ### Running Python ml-metadata test client +Before running the test client, install the required Python libraries (using a python venv, if using one) +using the command: +``` +pip install ml_metadata grpcio +``` Run the following command to run the ml-metadata Python test client: ``` make run/client From a1e8195b5485e3b4480a8e64febc3d8ee811058b Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 5 Sep 2023 18:30:08 -0700 Subject: [PATCH 023/254] Fixed makefile to create sqlite DB automatically --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index efede0f9..18102e82 100644 --- a/Makefile +++ b/Makefile @@ -36,8 +36,10 @@ gen: gen/grpc gen/graph run/migrate: gen go run main.go migrate --logtostderr=true +metadata.sqlite.db: run/migrate + .PHONY: run/server -run/server: gen +run/server: gen metadata.sqlite.db go run main.go serve --logtostderr=true .PHONY: run/client From ba454ccd6d0bc7e25d9dc2a661baed6582131669 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 6 Sep 2023 10:39:41 -0700 Subject: [PATCH 024/254] Fixed metadata library properties parsing --- cmd/migrate.go | 176 +++++++----- .../metadata-library/ml-metadata-library.yaml | 2 + go.mod | 3 + go.sum | 6 + model/library/metadata_library.go | 56 ++++ model/library/propertytype_enum.go | 271 ++++++++++++++++++ server/library/metadata_library.go | 34 --- tools.go | 6 +- 8 files changed, 439 insertions(+), 115 deletions(-) create mode 100644 model/library/metadata_library.go create mode 100644 model/library/propertytype_enum.go delete mode 100644 server/library/metadata_library.go diff --git a/cmd/migrate.go b/cmd/migrate.go index 9f588efb..5c7dfcaf 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -20,11 +20,12 @@ import ( "fmt" "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" "github.com/dhirajsb/ml-metadata-go-server/model/db" + "github.com/dhirajsb/ml-metadata-go-server/model/library" "github.com/dhirajsb/ml-metadata-go-server/server" - "github.com/dhirajsb/ml-metadata-go-server/server/library" "github.com/golang/glog" "github.com/spf13/cobra" yaml "gopkg.in/yaml.v3" + "gorm.io/gorm" "io/fs" "os" "path/filepath" @@ -57,94 +58,113 @@ to the latest schema required by this server.`, return fmt.Errorf("db connection failed: %w", err) } // migrate all DB types - // TODO add support for more elaborate Gorm migrations - err = dbConn.AutoMigrate( - db.Artifact{}, - db.ArtifactProperty{}, - db.Association{}, - db.Attribution{}, - db.Context{}, - db.ContextProperty{}, - db.Event{}, - db.EventPath{}, - db.Execution{}, - db.ExecutionProperty{}, - db.ParentContext{}, - db.Type{}, - db.TypeProperty{}, - ) + err = migrateDatabase(dbConn) if err != nil { - return fmt.Errorf("db migration failed: %w", err) + return err } // load metadata type libraries - for _, dir := range libraryDirs { - abs, err := filepath.Abs(dir) + err = loadLibraries(dbConn) + if err != nil { + return err + } + return nil + }, +} + +func migrateDatabase(dbConn *gorm.DB) error { + // TODO add support for more elaborate Gorm migrations + err := dbConn.AutoMigrate( + db.Artifact{}, + db.ArtifactProperty{}, + db.Association{}, + db.Attribution{}, + db.Context{}, + db.ContextProperty{}, + db.Event{}, + db.EventPath{}, + db.Execution{}, + db.ExecutionProperty{}, + db.ParentContext{}, + db.Type{}, + db.TypeProperty{}, + ) + if err != nil { + return fmt.Errorf("db migration failed: %w", err) + } + return nil +} + +func loadLibraries(dbConn *gorm.DB) error { + for _, dir := range libraryDirs { + abs, err := filepath.Abs(dir) + if err != nil { + return fmt.Errorf("error getting absolute library path for %s: %w", dir, err) + } + _, err = os.Stat(abs) + if err != nil { + return fmt.Errorf("error opening library path for %s: %w", abs, err) + } + err = filepath.WalkDir(abs, func(path string, entry fs.DirEntry, err error) error { if err != nil { - return fmt.Errorf("error getting absolute library path for %s: %w", dir, err) + glog.Warningf("error reading library path %s: %v", path, err) + return filepath.SkipDir } - _, err = os.Stat(abs) - if err != nil { - return fmt.Errorf("error opening library path for %s: %w", abs, err) + if entry.IsDir() || !isYamlFile(path) { + return nil } - err = filepath.WalkDir(abs, func(path string, entry fs.DirEntry, err error) error { - if err != nil { - glog.Warningf("error reading library path %s: %v", path, err) - return filepath.SkipDir - } - if entry.IsDir() || !isYamlFile(path) { - return nil - } - bytes, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("failed to read library file %s: %w", path, err) - } - var lib library.MetadataLibrary - err = yaml.Unmarshal(bytes, &lib) - grpcServer := server.NewGrpcServer(dbConn) - typesRequest := proto.PutTypesRequest{} - for _, ar := range lib.ArtifactTypes { - typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ - Name: ar.Name, - Version: ar.Version, - Description: ar.Description, - ExternalId: ar.ExternalId, - Properties: ar.Properties, - }) - } - for _, ar := range lib.ContextTypes { - typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ - Name: ar.Name, - Version: ar.Version, - Description: ar.Description, - ExternalId: ar.ExternalId, - Properties: ar.Properties, - }) - } - for _, ar := range lib.ExecutionTypes { - typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ - Name: ar.Name, - Version: ar.Version, - Description: ar.Description, - ExternalId: ar.ExternalId, - Properties: ar.Properties, - }) - } - response, err := grpcServer.PutTypes(context.Background(), &typesRequest) - if err != nil { - return fmt.Errorf("failed to add library from file %s: %w", path, err) - } - glog.Infof("added %d artifacts, %d contexts and %d execution types from library file %s", - len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) - return nil - }) + bytes, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read library file %s: %w", path, err) + } + var lib library.MetadataLibrary + err = yaml.Unmarshal(bytes, &lib) if err != nil { - return fmt.Errorf("failed to read library directory %s: %w", abs, err) + return fmt.Errorf("failed to parse library file %s: %w", path, err) } + grpcServer := server.NewGrpcServer(dbConn) + typesRequest := proto.PutTypesRequest{} + for _, at := range lib.ArtifactTypes { + typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ + Name: at.Name, + Version: at.Version, + Description: at.Description, + ExternalId: at.ExternalId, + Properties: library.ToProtoProperties(at.Properties), + }) + } + for _, ct := range lib.ContextTypes { + typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ + Name: ct.Name, + Version: ct.Version, + Description: ct.Description, + ExternalId: ct.ExternalId, + Properties: library.ToProtoProperties(ct.Properties), + }) + } + for _, et := range lib.ExecutionTypes { + typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ + Name: et.Name, + Version: et.Version, + Description: et.Description, + ExternalId: et.ExternalId, + Properties: library.ToProtoProperties(et.Properties), + }) + } + response, err := grpcServer.PutTypes(context.Background(), &typesRequest) + if err != nil { + return fmt.Errorf("failed to add library from file %s: %w", path, err) + } + glog.Infof("added %d artifacts, %d contexts and %d execution types from library file %s", + len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) + return nil + }) + if err != nil { + return fmt.Errorf("failed to read library directory %s: %w", abs, err) } - return nil - }, + } + return nil } func isYamlFile(path string) bool { diff --git a/config/metadata-library/ml-metadata-library.yaml b/config/metadata-library/ml-metadata-library.yaml index bf694128..991a62a4 100644 --- a/config/metadata-library/ml-metadata-library.yaml +++ b/config/metadata-library/ml-metadata-library.yaml @@ -1,6 +1,8 @@ # types for ml-metadata library artifact-types: - name: "mlmd.Dataset" + properties: + "note": STRING - name: "mlmd.Model" - name: "mlmd.Metrics" - name: "mlmd.Statistics" diff --git a/go.mod b/go.mod index 9921cf97..14ebc9d8 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/99designs/gqlgen v0.17.36 github.com/golang/glog v1.1.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 + github.com/searKing/golang/tools/go-enum v1.2.97 github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 @@ -35,6 +36,8 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/searKing/golang/go v1.2.52 // indirect + github.com/searKing/golang/tools v1.2.29 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect diff --git a/go.sum b/go.sum index 6dc5c69d..8d23e819 100644 --- a/go.sum +++ b/go.sum @@ -178,6 +178,12 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/searKing/golang/go v1.2.52 h1:Nbsr8HIS4ATL7LY1BE3SwRyEQd+UkrRymyol46sXb3s= +github.com/searKing/golang/go v1.2.52/go.mod h1:9AhTd9NFW/ck459PgNJwBA6I5q/ZBt9qOSvv9oZvHgA= +github.com/searKing/golang/tools v1.2.29 h1:gWX4aCA1+N7CfLpNd6tmBjYtecTksZFXziqbQ+AJKLo= +github.com/searKing/golang/tools v1.2.29/go.mod h1:QtwFM73H1qMKlRl0p8NRWXrNaCaffoYkNHk5YMoRyOY= +github.com/searKing/golang/tools/go-enum v1.2.97 h1:mX396oCnjdGqmMmwffBwpEU3L1X/7K3eDuXOOLow+TQ= +github.com/searKing/golang/tools/go-enum v1.2.97/go.mod h1:gWZ/vkIPpA0nCHDMETjzKqsHPDWSPdhZeXPxf/jWyqA= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= diff --git a/model/library/metadata_library.go b/model/library/metadata_library.go new file mode 100644 index 00000000..6e9a5e96 --- /dev/null +++ b/model/library/metadata_library.go @@ -0,0 +1,56 @@ +package library + +import "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" + +//go:generate go-enum -type=PropertyType + +type PropertyType int32 + +const ( + UNKNOWN PropertyType = iota + INT + DOUBLE + STRING + STRUCT + PROTO + BOOLEAN +) + +type MetadataType struct { + Name *string `yaml:"name,omitempty"` + Version *string `yaml:"version,omitempty"` + Description *string `yaml:"description,omitempty"` + ExternalId *string `yaml:"external_id,omitempty"` + Properties map[string]PropertyType `yaml:"properties,omitempty"` +} + +type ArtifactType struct { + MetadataType `yaml:",inline"` + // TODO add support for base type enum + //BaseType *ArtifactType_SystemDefinedBaseType `yaml:"base_type,omitempty"` +} + +type ContextType struct { + MetadataType `yaml:",inline"` +} + +type ExecutionType struct { + MetadataType `yaml:",inline"` + //InputType *ArtifactStructType `yaml:"input_type,omitempty"` + //OutputType *ArtifactStructType `yaml:"output_type,omitempty"` + //BaseType *ExecutionType_SystemDefinedBaseType `yaml:"base_type,omitempty"` +} + +type MetadataLibrary struct { + ArtifactTypes []ArtifactType `yaml:"artifact-types,omitempty"` + ContextTypes []ContextType `yaml:"context-types,omitempty"` + ExecutionTypes []ExecutionType `yaml:"execution-types,omitempty"` +} + +func ToProtoProperties(props map[string]PropertyType) map[string]proto.PropertyType { + result := make(map[string]proto.PropertyType) + for name, prop := range props { + result[name] = proto.PropertyType(prop) + } + return result +} diff --git a/model/library/propertytype_enum.go b/model/library/propertytype_enum.go new file mode 100644 index 00000000..1c575b5e --- /dev/null +++ b/model/library/propertytype_enum.go @@ -0,0 +1,271 @@ +// Code generated by "go-enum -type=PropertyType"; DO NOT EDIT. + +// Install go-enum by `go get install github.com/searKing/golang/tools/go-enum` +package library + +import ( + "database/sql" + "database/sql/driver" + "encoding" + "encoding/json" + "fmt" + "strconv" +) + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[UNKNOWN-0] + _ = x[INT-1] + _ = x[DOUBLE-2] + _ = x[STRING-3] + _ = x[STRUCT-4] + _ = x[PROTO-5] + _ = x[BOOLEAN-6] +} + +const _PropertyType_name = "UNKNOWNINTDOUBLESTRINGSTRUCTPROTOBOOLEAN" + +var _PropertyType_index = [...]uint8{0, 7, 10, 16, 22, 28, 33, 40} + +func _() { + var _nil_PropertyType_value = func() (val PropertyType) { return }() + + // An "cannot convert PropertyType literal (type PropertyType) to type fmt.Stringer" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ fmt.Stringer = _nil_PropertyType_value +} + +func (i PropertyType) String() string { + if i < 0 || i >= PropertyType(len(_PropertyType_index)-1) { + return "PropertyType(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _PropertyType_name[_PropertyType_index[i]:_PropertyType_index[i+1]] +} + +// New returns a pointer to a new addr filled with the PropertyType value passed in. +func (i PropertyType) New() *PropertyType { + clone := i + return &clone +} + +var _PropertyType_values = []PropertyType{0, 1, 2, 3, 4, 5, 6} + +var _PropertyType_name_to_values = map[string]PropertyType{ + _PropertyType_name[0:7]: 0, + _PropertyType_name[7:10]: 1, + _PropertyType_name[10:16]: 2, + _PropertyType_name[16:22]: 3, + _PropertyType_name[22:28]: 4, + _PropertyType_name[28:33]: 5, + _PropertyType_name[33:40]: 6, +} + +// ParsePropertyTypeString retrieves an enum value from the enum constants string name. +// Throws an error if the param is not part of the enum. +func ParsePropertyTypeString(s string) (PropertyType, error) { + if val, ok := _PropertyType_name_to_values[s]; ok { + return val, nil + } + return 0, fmt.Errorf("%s does not belong to PropertyType values", s) +} + +// PropertyTypeValues returns all values of the enum +func PropertyTypeValues() []PropertyType { + return _PropertyType_values +} + +// IsAPropertyType returns "true" if the value is listed in the enum definition. "false" otherwise +func (i PropertyType) Registered() bool { + for _, v := range _PropertyType_values { + if i == v { + return true + } + } + return false +} + +func _() { + var _nil_PropertyType_value = func() (val PropertyType) { return }() + + // An "cannot convert PropertyType literal (type PropertyType) to type encoding.BinaryMarshaler" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ encoding.BinaryMarshaler = &_nil_PropertyType_value + + // An "cannot convert PropertyType literal (type PropertyType) to type encoding.BinaryUnmarshaler" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ encoding.BinaryUnmarshaler = &_nil_PropertyType_value +} + +// MarshalBinary implements the encoding.BinaryMarshaler interface for PropertyType +func (i PropertyType) MarshalBinary() (data []byte, err error) { + return []byte(i.String()), nil +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface for PropertyType +func (i *PropertyType) UnmarshalBinary(data []byte) error { + var err error + *i, err = ParsePropertyTypeString(string(data)) + return err +} + +func _() { + var _nil_PropertyType_value = func() (val PropertyType) { return }() + + // An "cannot convert PropertyType literal (type PropertyType) to type json.Marshaler" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ json.Marshaler = _nil_PropertyType_value + + // An "cannot convert PropertyType literal (type PropertyType) to type encoding.Unmarshaler" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ json.Unmarshaler = &_nil_PropertyType_value +} + +// MarshalJSON implements the json.Marshaler interface for PropertyType +func (i PropertyType) MarshalJSON() ([]byte, error) { + return json.Marshal(i.String()) +} + +// UnmarshalJSON implements the json.Unmarshaler interface for PropertyType +func (i *PropertyType) UnmarshalJSON(data []byte) error { + var s string + if err := json.Unmarshal(data, &s); err != nil { + return fmt.Errorf("PropertyType should be a string, got %s", data) + } + + var err error + *i, err = ParsePropertyTypeString(s) + return err +} + +func _() { + var _nil_PropertyType_value = func() (val PropertyType) { return }() + + // An "cannot convert PropertyType literal (type PropertyType) to type encoding.TextMarshaler" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ encoding.TextMarshaler = _nil_PropertyType_value + + // An "cannot convert PropertyType literal (type PropertyType) to type encoding.TextUnmarshaler" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ encoding.TextUnmarshaler = &_nil_PropertyType_value +} + +// MarshalText implements the encoding.TextMarshaler interface for PropertyType +func (i PropertyType) MarshalText() ([]byte, error) { + return []byte(i.String()), nil +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface for PropertyType +func (i *PropertyType) UnmarshalText(text []byte) error { + var err error + *i, err = ParsePropertyTypeString(string(text)) + return err +} + +//func _() { +// var _nil_PropertyType_value = func() (val PropertyType) { return }() +// +// // An "cannot convert PropertyType literal (type PropertyType) to type yaml.Marshaler" compiler error signifies that the base type have changed. +// // Re-run the go-enum command to generate them again. +// var _ yaml.Marshaler = _nil_PropertyType_value +// +// // An "cannot convert PropertyType literal (type PropertyType) to type yaml.Unmarshaler" compiler error signifies that the base type have changed. +// // Re-run the go-enum command to generate them again. +// var _ yaml.Unmarshaler = &_nil_PropertyType_value +//} + +// MarshalYAML implements a YAML Marshaler for PropertyType +func (i PropertyType) MarshalYAML() (interface{}, error) { + return i.String(), nil +} + +// UnmarshalYAML implements a YAML Unmarshaler for PropertyType +func (i *PropertyType) UnmarshalYAML(unmarshal func(interface{}) error) error { + var s string + if err := unmarshal(&s); err != nil { + return err + } + + var err error + *i, err = ParsePropertyTypeString(s) + return err +} + +func _() { + var _nil_PropertyType_value = func() (val PropertyType) { return }() + + // An "cannot convert PropertyType literal (type PropertyType) to type driver.Valuer" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ driver.Valuer = _nil_PropertyType_value + + // An "cannot convert PropertyType literal (type PropertyType) to type sql.Scanner" compiler error signifies that the base type have changed. + // Re-run the go-enum command to generate them again. + var _ sql.Scanner = &_nil_PropertyType_value +} + +func (i PropertyType) Value() (driver.Value, error) { + return i.String(), nil +} + +func (i *PropertyType) Scan(value interface{}) error { + if value == nil { + return nil + } + + str, ok := value.(string) + if !ok { + bytes, ok := value.([]byte) + if !ok { + return fmt.Errorf("value is not a byte slice") + } + + str = string(bytes[:]) + } + + val, err := ParsePropertyTypeString(str) + if err != nil { + return err + } + + *i = val + return nil +} + +// PropertyTypeSliceContains reports whether sunEnums is within enums. +func PropertyTypeSliceContains(enums []PropertyType, sunEnums ...PropertyType) bool { + var seenEnums = map[PropertyType]bool{} + for _, e := range sunEnums { + seenEnums[e] = false + } + + for _, v := range enums { + if _, has := seenEnums[v]; has { + seenEnums[v] = true + } + } + + for _, seen := range seenEnums { + if !seen { + return false + } + } + + return true +} + +// PropertyTypeSliceContainsAny reports whether any sunEnum is within enums. +func PropertyTypeSliceContainsAny(enums []PropertyType, sunEnums ...PropertyType) bool { + var seenEnums = map[PropertyType]struct{}{} + for _, e := range sunEnums { + seenEnums[e] = struct{}{} + } + + for _, v := range enums { + if _, has := seenEnums[v]; has { + return true + } + } + + return false +} diff --git a/server/library/metadata_library.go b/server/library/metadata_library.go deleted file mode 100644 index ad0fd7a3..00000000 --- a/server/library/metadata_library.go +++ /dev/null @@ -1,34 +0,0 @@ -package library - -import "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" - -type MetadataType struct { - Name *string `yaml:"name,omitempty"` - Version *string `yaml:"version,omitempty"` - Description *string `yaml:"description,omitempty"` - ExternalId *string `yaml:"external_id,omitempty"` - Properties map[string]proto.PropertyType `yaml:"properties,omitempty"` -} - -type ArtifactType struct { - MetadataType `yaml:",inline"` - // TODO add support for base type enum - //BaseType *ArtifactType_SystemDefinedBaseType `yaml:"base_type,omitempty"` -} - -type ContextType struct { - MetadataType `yaml:",inline"` -} - -type ExecutionType struct { - MetadataType `yaml:",inline"` - //InputType *ArtifactStructType `yaml:"input_type,omitempty"` - //OutputType *ArtifactStructType `yaml:"output_type,omitempty"` - //BaseType *ExecutionType_SystemDefinedBaseType `yaml:"base_type,omitempty"` -} - -type MetadataLibrary struct { - ArtifactTypes []ArtifactType `yaml:"artifact-types,omitempty"` - ContextTypes []ArtifactType `yaml:"context-types,omitempty"` - ExecutionTypes []ArtifactType `yaml:"execution-types,omitempty"` -} diff --git a/tools.go b/tools.go index ad5606e8..0ce5e195 100644 --- a/tools.go +++ b/tools.go @@ -1,11 +1,11 @@ //go:build tools -// +build tools package tools import ( - _ "google.golang.org/protobuf/cmd/protoc-gen-go" - _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" _ "github.com/99designs/gqlgen" _ "github.com/99designs/gqlgen/graphql/introspection" + _ "github.com/searKing/golang/tools/go-enum" + _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" + _ "google.golang.org/protobuf/cmd/protoc-gen-go" ) From a24e1ba733ea454c29bbdcf557f736f7bc1d69f6 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 7 Sep 2023 10:28:37 -0700 Subject: [PATCH 025/254] Fixed mock graphql schemas --- api/graphql/base-schema.graphqls | 175 + api/graphql/ml-metadata.graphqls | 99 + api/graphql/schema.graphqls | 145 +- .../mlflow-metadata-library.yaml | 27 - .../mlschema-metadata-library.yaml | 27 + model/graph/models_gen.go | 342 +- server/graph/base-schema.resolvers.go | 22 + server/graph/generated.go | 10750 +++++++++++----- server/graph/schema.resolvers.go | 13 +- 9 files changed, 8507 insertions(+), 3093 deletions(-) create mode 100644 api/graphql/base-schema.graphqls create mode 100644 api/graphql/ml-metadata.graphqls delete mode 100644 config/metadata-library/mlflow-metadata-library.yaml create mode 100644 config/metadata-library/mlschema-metadata-library.yaml create mode 100644 server/graph/base-schema.resolvers.go diff --git a/api/graphql/base-schema.graphqls b/api/graphql/base-schema.graphqls new file mode 100644 index 00000000..f615aed3 --- /dev/null +++ b/api/graphql/base-schema.graphqls @@ -0,0 +1,175 @@ +type Artifact { + id: ID + typeId: ID! + uri: String! + state: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type(filter: InstanceFilter): ArtifactType! + properties : [ArtifactProperty!] +} + +type ArtifactProperty { + artifactId: ID + name: String + isCustomProperty: Boolean! + propertyValue: Value! +} + +type Context { + id: ID + typeId: ID! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ContextType! + parent: Context + children: [Context] + attributions: [Artifact!] + associations: [Execution!] + properties: [ContextProperty!] +} + +type ContextProperty { + contextId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +type Event { + id: ID + artifactId: ID! + executionId: ID! + type: Int! + artifact: Artifact + execution: Execution + millisecondsSinceEpoch: Int! +} + +type EventPath { + eventId: ID! + isIndexStep: Int! + stepIndex: Int! + stepKey: String! +} + +type Execution { + id: ID + typeId: ID! + lastKnownState: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ExecutionType! + properties: [ExecutionProperty!] +} + +type ExecutionProperty { + executionId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +union Value = IntValue | DoubleValue | StringValue | BoolValue + +type IntValue { + value: Int! +} + +type DoubleValue { + value: Float! +} + +type StringValue { + value: String! +} + +type BoolValue { + value: Boolean! +} + +interface Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type TypeProperty { + typeId: ID! + name: String! + dataType: Int! +} + +interface ArtifactTypeInterface implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ArtifactType implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +interface ContextTypeInterface implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ContextType implements ContextTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +interface ExecutionTypeInterface implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type ExecutionType implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} diff --git a/api/graphql/ml-metadata.graphqls b/api/graphql/ml-metadata.graphqls new file mode 100644 index 00000000..2531754a --- /dev/null +++ b/api/graphql/ml-metadata.graphqls @@ -0,0 +1,99 @@ +type MlmdDataset implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdModel implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdMetrics implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdStatistics implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdTrain implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdTransform implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdProcess implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdEvaluate implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdDeploy implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} diff --git a/api/graphql/schema.graphqls b/api/graphql/schema.graphqls index 8a94177a..945a9f87 100644 --- a/api/graphql/schema.graphqls +++ b/api/graphql/schema.graphqls @@ -1,147 +1,3 @@ -type Artifact { - id: ID - typeId: ID! - uri: String! - state: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ArtifactType! - properties : [ArtifactProperty!] -} - -type ArtifactProperty { - artifactId: ID - name: String - isCustomProperty: Boolean! - propertyValue: Value! -} - -type Context { - id: ID - typeId: ID! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ContextType! - parent: Context - children: [Context] - attributions: [Artifact!] - associations: [Execution!] - properties: [ContextProperty!] -} - -type ContextProperty { - contextId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} - -type Event { - id: ID - artifactId: ID! - executionId: ID! - type: Int! - artifact: Artifact - execution: Execution - millisecondsSinceEpoch: Int! -} - -type EventPath { - eventId: ID! - isIndexStep: Int! - stepIndex: Int! - stepKey: String! -} - -type Execution { - id: ID - typeId: ID! - lastKnownState: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ExecutionType! - properties: [ExecutionProperty!] -} - -type ExecutionProperty { - executionId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} - -union Value = IntValue | DoubleValue | StringValue | BoolValue - -type IntValue { - value: Int! -} - -type DoubleValue { - value: Float! -} - -type StringValue { - value: String! -} - -type BoolValue { - value: Boolean! -} - -interface Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type TypeProperty { - typeId: ID! - name: String! - dataType: Int! -} - -type ArtifactType implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type ContextType implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type ExecutionType implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - input TypeFilter { ids: [ID!] names: [String!] @@ -165,4 +21,5 @@ type Query { contexts(filter: InstanceFilter): [Context!] executions(filter: InstanceFilter): [Execution!] events: [Event!] + mlmdDataset(filter: InstanceFilter): [MlmdDataset!] } diff --git a/config/metadata-library/mlflow-metadata-library.yaml b/config/metadata-library/mlflow-metadata-library.yaml deleted file mode 100644 index b0ec693e..00000000 --- a/config/metadata-library/mlflow-metadata-library.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# types for ml-metadata library -artifact-types: - - name: "mlflow.Model" - - name: "mlflow.ModelEvaluation" - - name: "mlflow.EvaluationMeasure" - - name: "mlflow.EvaluationSpecification" - - name: "mlflow.EvaluationProcedure" - - name: "mlflow.Task" - - name: "mlflow.Data" - - name: "mlflow.DataSet" - - name: "mlflow.Feature" - - name: "mlflow.Algorithm" - - name: "mlflow.Software" - - name: "mlflow.Implementation" - - name: "mlflow.HyperParameter" - - name: "mlflow.HyperParameterSetting" - - name: "mlflow.ImplementationCharacteristic" - - name: "mlflow.DatasetCharacteristic" - - name: "mlflow.FeatureCharacteristic" -context-types: - - name: "mlflow.RegisteredModel" - - name: "mlflow.ModelVersion" - - name: "mlflow.DataCharacteristic" -execution-types: - - name: "mlflow.Study" - - name: "mlflow.Experiment" - - name: "mlflow.Run" diff --git a/config/metadata-library/mlschema-metadata-library.yaml b/config/metadata-library/mlschema-metadata-library.yaml new file mode 100644 index 00000000..6fa21269 --- /dev/null +++ b/config/metadata-library/mlschema-metadata-library.yaml @@ -0,0 +1,27 @@ +# types for ml-metadata library +artifact-types: + - name: "mlschema.Model" + - name: "mlschema.ModelEvaluation" + - name: "mlschema.EvaluationMeasure" + - name: "mlschema.EvaluationSpecification" + - name: "mlschema.EvaluationProcedure" + - name: "mlschema.Task" + - name: "mlschema.Data" + - name: "mlschema.DataSet" + - name: "mlschema.Feature" + - name: "mlschema.Algorithm" + - name: "mlschema.Software" + - name: "mlschema.Implementation" + - name: "mlschema.HyperParameter" + - name: "mlschema.HyperParameterSetting" + - name: "mlschema.ImplementationCharacteristic" + - name: "mlschema.DatasetCharacteristic" + - name: "mlschema.FeatureCharacteristic" +context-types: + - name: "mlschema.RegisteredModel" + - name: "mlschema.ModelVersion" + - name: "mlschema.DataCharacteristic" +execution-types: + - name: "mlschema.Study" + - name: "mlschema.Experiment" + - name: "mlschema.Run" diff --git a/model/graph/models_gen.go b/model/graph/models_gen.go index c54f1ebe..91bcef90 100644 --- a/model/graph/models_gen.go +++ b/model/graph/models_gen.go @@ -2,6 +2,44 @@ package graph +type ArtifactTypeInterface interface { + IsType() + IsArtifactTypeInterface() + GetID() *string + GetName() string + GetVersion() string + GetTypeKind() int + GetDescription() string + GetExternalID() *string + GetProperties() []*TypeProperty +} + +type ContextTypeInterface interface { + IsType() + IsContextTypeInterface() + GetID() *string + GetName() string + GetVersion() string + GetTypeKind() int + GetDescription() string + GetExternalID() *string + GetProperties() []*TypeProperty +} + +type ExecutionTypeInterface interface { + IsType() + IsExecutionTypeInterface() + GetID() *string + GetName() string + GetVersion() string + GetTypeKind() int + GetDescription() string + GetExternalID() *string + GetInputType() string + GetOutputType() string + GetProperties() []*TypeProperty +} + type Type interface { IsType() GetID() *string @@ -47,7 +85,7 @@ type ArtifactType struct { Properties []*TypeProperty `json:"properties,omitempty"` } -func (ArtifactType) IsType() {} +func (ArtifactType) IsArtifactTypeInterface() {} func (this ArtifactType) GetID() *string { return this.ID } func (this ArtifactType) GetName() string { return this.Name } func (this ArtifactType) GetVersion() string { return this.Version } @@ -65,6 +103,8 @@ func (this ArtifactType) GetProperties() []*TypeProperty { return interfaceSlice } +func (ArtifactType) IsType() {} + type BoolValue struct { Value bool `json:"value"` } @@ -103,7 +143,7 @@ type ContextType struct { Properties []*TypeProperty `json:"properties,omitempty"` } -func (ContextType) IsType() {} +func (ContextType) IsContextTypeInterface() {} func (this ContextType) GetID() *string { return this.ID } func (this ContextType) GetName() string { return this.Name } func (this ContextType) GetVersion() string { return this.Version } @@ -121,6 +161,8 @@ func (this ContextType) GetProperties() []*TypeProperty { return interfaceSlice } +func (ContextType) IsType() {} + type DoubleValue struct { Value float64 `json:"value"` } @@ -175,13 +217,15 @@ type ExecutionType struct { Properties []*TypeProperty `json:"properties,omitempty"` } -func (ExecutionType) IsType() {} +func (ExecutionType) IsExecutionTypeInterface() {} func (this ExecutionType) GetID() *string { return this.ID } func (this ExecutionType) GetName() string { return this.Name } func (this ExecutionType) GetVersion() string { return this.Version } func (this ExecutionType) GetTypeKind() int { return this.TypeKind } func (this ExecutionType) GetDescription() string { return this.Description } func (this ExecutionType) GetExternalID() *string { return this.ExternalID } +func (this ExecutionType) GetInputType() string { return this.InputType } +func (this ExecutionType) GetOutputType() string { return this.OutputType } func (this ExecutionType) GetProperties() []*TypeProperty { if this.Properties == nil { return nil @@ -193,6 +237,8 @@ func (this ExecutionType) GetProperties() []*TypeProperty { return interfaceSlice } +func (ExecutionType) IsType() {} + type InstanceFilter struct { Ids []string `json:"ids,omitempty"` TypeIds []string `json:"typeIds,omitempty"` @@ -206,6 +252,296 @@ type IntValue struct { func (IntValue) IsValue() {} +type MlmdDataset struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdDataset) IsArtifactTypeInterface() {} +func (this MlmdDataset) GetID() *string { return this.ID } +func (this MlmdDataset) GetName() string { return this.Name } +func (this MlmdDataset) GetVersion() string { return this.Version } +func (this MlmdDataset) GetTypeKind() int { return this.TypeKind } +func (this MlmdDataset) GetDescription() string { return this.Description } +func (this MlmdDataset) GetExternalID() *string { return this.ExternalID } +func (this MlmdDataset) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdDataset) IsType() {} + +type MlmdDeploy struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + InputType string `json:"inputType"` + OutputType string `json:"outputType"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdDeploy) IsExecutionTypeInterface() {} +func (this MlmdDeploy) GetID() *string { return this.ID } +func (this MlmdDeploy) GetName() string { return this.Name } +func (this MlmdDeploy) GetVersion() string { return this.Version } +func (this MlmdDeploy) GetTypeKind() int { return this.TypeKind } +func (this MlmdDeploy) GetDescription() string { return this.Description } +func (this MlmdDeploy) GetExternalID() *string { return this.ExternalID } +func (this MlmdDeploy) GetInputType() string { return this.InputType } +func (this MlmdDeploy) GetOutputType() string { return this.OutputType } +func (this MlmdDeploy) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdDeploy) IsType() {} + +type MlmdEvaluate struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + InputType string `json:"inputType"` + OutputType string `json:"outputType"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdEvaluate) IsExecutionTypeInterface() {} +func (this MlmdEvaluate) GetID() *string { return this.ID } +func (this MlmdEvaluate) GetName() string { return this.Name } +func (this MlmdEvaluate) GetVersion() string { return this.Version } +func (this MlmdEvaluate) GetTypeKind() int { return this.TypeKind } +func (this MlmdEvaluate) GetDescription() string { return this.Description } +func (this MlmdEvaluate) GetExternalID() *string { return this.ExternalID } +func (this MlmdEvaluate) GetInputType() string { return this.InputType } +func (this MlmdEvaluate) GetOutputType() string { return this.OutputType } +func (this MlmdEvaluate) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdEvaluate) IsType() {} + +type MlmdMetrics struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdMetrics) IsArtifactTypeInterface() {} +func (this MlmdMetrics) GetID() *string { return this.ID } +func (this MlmdMetrics) GetName() string { return this.Name } +func (this MlmdMetrics) GetVersion() string { return this.Version } +func (this MlmdMetrics) GetTypeKind() int { return this.TypeKind } +func (this MlmdMetrics) GetDescription() string { return this.Description } +func (this MlmdMetrics) GetExternalID() *string { return this.ExternalID } +func (this MlmdMetrics) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdMetrics) IsType() {} + +type MlmdModel struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdModel) IsArtifactTypeInterface() {} +func (this MlmdModel) GetID() *string { return this.ID } +func (this MlmdModel) GetName() string { return this.Name } +func (this MlmdModel) GetVersion() string { return this.Version } +func (this MlmdModel) GetTypeKind() int { return this.TypeKind } +func (this MlmdModel) GetDescription() string { return this.Description } +func (this MlmdModel) GetExternalID() *string { return this.ExternalID } +func (this MlmdModel) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdModel) IsType() {} + +type MlmdProcess struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + InputType string `json:"inputType"` + OutputType string `json:"outputType"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdProcess) IsExecutionTypeInterface() {} +func (this MlmdProcess) GetID() *string { return this.ID } +func (this MlmdProcess) GetName() string { return this.Name } +func (this MlmdProcess) GetVersion() string { return this.Version } +func (this MlmdProcess) GetTypeKind() int { return this.TypeKind } +func (this MlmdProcess) GetDescription() string { return this.Description } +func (this MlmdProcess) GetExternalID() *string { return this.ExternalID } +func (this MlmdProcess) GetInputType() string { return this.InputType } +func (this MlmdProcess) GetOutputType() string { return this.OutputType } +func (this MlmdProcess) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdProcess) IsType() {} + +type MlmdStatistics struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdStatistics) IsArtifactTypeInterface() {} +func (this MlmdStatistics) GetID() *string { return this.ID } +func (this MlmdStatistics) GetName() string { return this.Name } +func (this MlmdStatistics) GetVersion() string { return this.Version } +func (this MlmdStatistics) GetTypeKind() int { return this.TypeKind } +func (this MlmdStatistics) GetDescription() string { return this.Description } +func (this MlmdStatistics) GetExternalID() *string { return this.ExternalID } +func (this MlmdStatistics) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdStatistics) IsType() {} + +type MlmdTrain struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + InputType string `json:"inputType"` + OutputType string `json:"outputType"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdTrain) IsExecutionTypeInterface() {} +func (this MlmdTrain) GetID() *string { return this.ID } +func (this MlmdTrain) GetName() string { return this.Name } +func (this MlmdTrain) GetVersion() string { return this.Version } +func (this MlmdTrain) GetTypeKind() int { return this.TypeKind } +func (this MlmdTrain) GetDescription() string { return this.Description } +func (this MlmdTrain) GetExternalID() *string { return this.ExternalID } +func (this MlmdTrain) GetInputType() string { return this.InputType } +func (this MlmdTrain) GetOutputType() string { return this.OutputType } +func (this MlmdTrain) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdTrain) IsType() {} + +type MlmdTransform struct { + ID *string `json:"id,omitempty"` + Name string `json:"name"` + Version string `json:"version"` + TypeKind int `json:"typeKind"` + Description string `json:"description"` + ExternalID *string `json:"externalId,omitempty"` + InputType string `json:"inputType"` + OutputType string `json:"outputType"` + Properties []*TypeProperty `json:"properties,omitempty"` +} + +func (MlmdTransform) IsExecutionTypeInterface() {} +func (this MlmdTransform) GetID() *string { return this.ID } +func (this MlmdTransform) GetName() string { return this.Name } +func (this MlmdTransform) GetVersion() string { return this.Version } +func (this MlmdTransform) GetTypeKind() int { return this.TypeKind } +func (this MlmdTransform) GetDescription() string { return this.Description } +func (this MlmdTransform) GetExternalID() *string { return this.ExternalID } +func (this MlmdTransform) GetInputType() string { return this.InputType } +func (this MlmdTransform) GetOutputType() string { return this.OutputType } +func (this MlmdTransform) GetProperties() []*TypeProperty { + if this.Properties == nil { + return nil + } + interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) + for _, concrete := range this.Properties { + interfaceSlice = append(interfaceSlice, concrete) + } + return interfaceSlice +} + +func (MlmdTransform) IsType() {} + type StringValue struct { Value string `json:"value"` } diff --git a/server/graph/base-schema.resolvers.go b/server/graph/base-schema.resolvers.go new file mode 100644 index 00000000..004fa1c2 --- /dev/null +++ b/server/graph/base-schema.resolvers.go @@ -0,0 +1,22 @@ +package graph + +// This file will be automatically regenerated based on the schema, any resolver implementations +// will be copied through when generating and any unknown code will be moved to the end. +// Code generated by github.com/99designs/gqlgen version v0.17.36 + +import ( + "context" + + "github.com/dhirajsb/ml-metadata-go-server/model/graph" +) + +// Type is the resolver for the type field. +func (r *artifactResolver) Type(ctx context.Context, obj *graph.Artifact, filter *graph.InstanceFilter) (*graph.ArtifactType, error) { + id := "1" + return &graph.ArtifactType{ID: &id, Name: "TestType"}, nil +} + +// Artifact returns ArtifactResolver implementation. +func (r *Resolver) Artifact() ArtifactResolver { return &artifactResolver{r} } + +type artifactResolver struct{ *Resolver } diff --git a/server/graph/generated.go b/server/graph/generated.go index 6babac01..16f2ae9a 100644 --- a/server/graph/generated.go +++ b/server/graph/generated.go @@ -52,7 +52,7 @@ type ComplexityRoot struct { Name func(childComplexity int) int Properties func(childComplexity int) int State func(childComplexity int) int - Type func(childComplexity int) int + Type func(childComplexity int, filter *graph.InstanceFilter) int TypeID func(childComplexity int) int URI func(childComplexity int) int } @@ -166,6 +166,106 @@ type ComplexityRoot struct { Value func(childComplexity int) int } + MlmdDataset struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdDeploy struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + InputType func(childComplexity int) int + Name func(childComplexity int) int + OutputType func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdEvaluate struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + InputType func(childComplexity int) int + Name func(childComplexity int) int + OutputType func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdMetrics struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdModel struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdProcess struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + InputType func(childComplexity int) int + Name func(childComplexity int) int + OutputType func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdStatistics struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + Name func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdTrain struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + InputType func(childComplexity int) int + Name func(childComplexity int) int + OutputType func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + + MlmdTransform struct { + Description func(childComplexity int) int + ExternalID func(childComplexity int) int + ID func(childComplexity int) int + InputType func(childComplexity int) int + Name func(childComplexity int) int + OutputType func(childComplexity int) int + Properties func(childComplexity int) int + TypeKind func(childComplexity int) int + Version func(childComplexity int) int + } + Query struct { ArtifactTypes func(childComplexity int, filter *graph.TypeFilter) int Artifacts func(childComplexity int, filter *graph.InstanceFilter) int @@ -174,6 +274,7 @@ type ComplexityRoot struct { Events func(childComplexity int) int ExecutionTypes func(childComplexity int, filter *graph.TypeFilter) int Executions func(childComplexity int, filter *graph.InstanceFilter) int + MlmdDataset func(childComplexity int, filter *graph.InstanceFilter) int Types func(childComplexity int, filter *graph.TypeFilter) int } @@ -189,7 +290,7 @@ type ComplexityRoot struct { } type ArtifactResolver interface { - Type(ctx context.Context, obj *graph.Artifact) (*graph.ArtifactType, error) + Type(ctx context.Context, obj *graph.Artifact, filter *graph.InstanceFilter) (*graph.ArtifactType, error) } type QueryResolver interface { Types(ctx context.Context, filter *graph.TypeFilter) ([]graph.Type, error) @@ -200,6 +301,7 @@ type QueryResolver interface { Contexts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Context, error) Executions(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Execution, error) Events(ctx context.Context) ([]*graph.Event, error) + MlmdDataset(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.MlmdDataset, error) } type executableSchema struct { @@ -271,7 +373,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in break } - return e.complexity.Artifact.Type(childComplexity), true + args, err := ec.field_Artifact_type_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Artifact.Type(childComplexity, args["filter"].(*graph.InstanceFilter)), true case "Artifact.typeId": if e.complexity.Artifact.TypeID == nil { @@ -777,1919 +884,5715 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.IntValue.Value(childComplexity), true - case "Query.artifactTypes": - if e.complexity.Query.ArtifactTypes == nil { + case "MlmdDataset.description": + if e.complexity.MlmdDataset.Description == nil { break } - args, err := ec.field_Query_artifactTypes_args(context.TODO(), rawArgs) - if err != nil { - return 0, false + return e.complexity.MlmdDataset.Description(childComplexity), true + + case "MlmdDataset.externalId": + if e.complexity.MlmdDataset.ExternalID == nil { + break } - return e.complexity.Query.ArtifactTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true + return e.complexity.MlmdDataset.ExternalID(childComplexity), true - case "Query.artifacts": - if e.complexity.Query.Artifacts == nil { + case "MlmdDataset.id": + if e.complexity.MlmdDataset.ID == nil { break } - args, err := ec.field_Query_artifacts_args(context.TODO(), rawArgs) - if err != nil { - return 0, false + return e.complexity.MlmdDataset.ID(childComplexity), true + + case "MlmdDataset.name": + if e.complexity.MlmdDataset.Name == nil { + break } - return e.complexity.Query.Artifacts(childComplexity, args["filter"].(*graph.InstanceFilter)), true + return e.complexity.MlmdDataset.Name(childComplexity), true - case "Query.contextTypes": - if e.complexity.Query.ContextTypes == nil { + case "MlmdDataset.properties": + if e.complexity.MlmdDataset.Properties == nil { break } - args, err := ec.field_Query_contextTypes_args(context.TODO(), rawArgs) - if err != nil { - return 0, false + return e.complexity.MlmdDataset.Properties(childComplexity), true + + case "MlmdDataset.typeKind": + if e.complexity.MlmdDataset.TypeKind == nil { + break } - return e.complexity.Query.ContextTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true + return e.complexity.MlmdDataset.TypeKind(childComplexity), true - case "Query.contexts": - if e.complexity.Query.Contexts == nil { + case "MlmdDataset.version": + if e.complexity.MlmdDataset.Version == nil { break } - args, err := ec.field_Query_contexts_args(context.TODO(), rawArgs) - if err != nil { - return 0, false + return e.complexity.MlmdDataset.Version(childComplexity), true + + case "MlmdDeploy.description": + if e.complexity.MlmdDeploy.Description == nil { + break } - return e.complexity.Query.Contexts(childComplexity, args["filter"].(*graph.InstanceFilter)), true + return e.complexity.MlmdDeploy.Description(childComplexity), true - case "Query.events": - if e.complexity.Query.Events == nil { + case "MlmdDeploy.externalId": + if e.complexity.MlmdDeploy.ExternalID == nil { break } - return e.complexity.Query.Events(childComplexity), true + return e.complexity.MlmdDeploy.ExternalID(childComplexity), true - case "Query.executionTypes": - if e.complexity.Query.ExecutionTypes == nil { + case "MlmdDeploy.id": + if e.complexity.MlmdDeploy.ID == nil { break } - args, err := ec.field_Query_executionTypes_args(context.TODO(), rawArgs) - if err != nil { - return 0, false + return e.complexity.MlmdDeploy.ID(childComplexity), true + + case "MlmdDeploy.inputType": + if e.complexity.MlmdDeploy.InputType == nil { + break } - return e.complexity.Query.ExecutionTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true + return e.complexity.MlmdDeploy.InputType(childComplexity), true - case "Query.executions": - if e.complexity.Query.Executions == nil { + case "MlmdDeploy.name": + if e.complexity.MlmdDeploy.Name == nil { break } - args, err := ec.field_Query_executions_args(context.TODO(), rawArgs) - if err != nil { - return 0, false + return e.complexity.MlmdDeploy.Name(childComplexity), true + + case "MlmdDeploy.outputType": + if e.complexity.MlmdDeploy.OutputType == nil { + break } - return e.complexity.Query.Executions(childComplexity, args["filter"].(*graph.InstanceFilter)), true + return e.complexity.MlmdDeploy.OutputType(childComplexity), true - case "Query.types": - if e.complexity.Query.Types == nil { + case "MlmdDeploy.properties": + if e.complexity.MlmdDeploy.Properties == nil { break } - args, err := ec.field_Query_types_args(context.TODO(), rawArgs) - if err != nil { - return 0, false + return e.complexity.MlmdDeploy.Properties(childComplexity), true + + case "MlmdDeploy.typeKind": + if e.complexity.MlmdDeploy.TypeKind == nil { + break } - return e.complexity.Query.Types(childComplexity, args["filter"].(*graph.TypeFilter)), true + return e.complexity.MlmdDeploy.TypeKind(childComplexity), true - case "StringValue.value": - if e.complexity.StringValue.Value == nil { + case "MlmdDeploy.version": + if e.complexity.MlmdDeploy.Version == nil { break } - return e.complexity.StringValue.Value(childComplexity), true + return e.complexity.MlmdDeploy.Version(childComplexity), true - case "TypeProperty.dataType": - if e.complexity.TypeProperty.DataType == nil { + case "MlmdEvaluate.description": + if e.complexity.MlmdEvaluate.Description == nil { break } - return e.complexity.TypeProperty.DataType(childComplexity), true + return e.complexity.MlmdEvaluate.Description(childComplexity), true - case "TypeProperty.name": - if e.complexity.TypeProperty.Name == nil { + case "MlmdEvaluate.externalId": + if e.complexity.MlmdEvaluate.ExternalID == nil { break } - return e.complexity.TypeProperty.Name(childComplexity), true + return e.complexity.MlmdEvaluate.ExternalID(childComplexity), true - case "TypeProperty.typeId": - if e.complexity.TypeProperty.TypeID == nil { + case "MlmdEvaluate.id": + if e.complexity.MlmdEvaluate.ID == nil { break } - return e.complexity.TypeProperty.TypeID(childComplexity), true + return e.complexity.MlmdEvaluate.ID(childComplexity), true - } - return 0, false -} + case "MlmdEvaluate.inputType": + if e.complexity.MlmdEvaluate.InputType == nil { + break + } -func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { - rc := graphql.GetOperationContext(ctx) - ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)} - inputUnmarshalMap := graphql.BuildUnmarshalerMap( - ec.unmarshalInputInstanceFilter, - ec.unmarshalInputTypeFilter, - ) - first := true + return e.complexity.MlmdEvaluate.InputType(childComplexity), true - switch rc.Operation.Operation { - case ast.Query: - return func(ctx context.Context) *graphql.Response { - var response graphql.Response - var data graphql.Marshaler - if first { - first = false - ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) - data = ec._Query(ctx, rc.Operation.SelectionSet) - } else { - if atomic.LoadInt32(&ec.pendingDeferred) > 0 { - result := <-ec.deferredResults - atomic.AddInt32(&ec.pendingDeferred, -1) - data = result.Result - response.Path = result.Path - response.Label = result.Label - response.Errors = result.Errors - } else { - return nil - } - } - var buf bytes.Buffer - data.MarshalGQL(&buf) - response.Data = buf.Bytes() - if atomic.LoadInt32(&ec.deferred) > 0 { - hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 - response.HasNext = &hasNext - } + case "MlmdEvaluate.name": + if e.complexity.MlmdEvaluate.Name == nil { + break + } - return &response + return e.complexity.MlmdEvaluate.Name(childComplexity), true + + case "MlmdEvaluate.outputType": + if e.complexity.MlmdEvaluate.OutputType == nil { + break } - default: - return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) - } -} + return e.complexity.MlmdEvaluate.OutputType(childComplexity), true -type executionContext struct { - *graphql.OperationContext - *executableSchema - deferred int32 - pendingDeferred int32 - deferredResults chan graphql.DeferredResult -} + case "MlmdEvaluate.properties": + if e.complexity.MlmdEvaluate.Properties == nil { + break + } -func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { - atomic.AddInt32(&ec.pendingDeferred, 1) - go func() { - ctx := graphql.WithFreshResponseContext(dg.Context) - dg.FieldSet.Dispatch(ctx) - ds := graphql.DeferredResult{ - Path: dg.Path, - Label: dg.Label, - Result: dg.FieldSet, - Errors: graphql.GetErrors(ctx), + return e.complexity.MlmdEvaluate.Properties(childComplexity), true + + case "MlmdEvaluate.typeKind": + if e.complexity.MlmdEvaluate.TypeKind == nil { + break } - // null fields should bubble up - if dg.FieldSet.Invalids > 0 { - ds.Result = graphql.Null + + return e.complexity.MlmdEvaluate.TypeKind(childComplexity), true + + case "MlmdEvaluate.version": + if e.complexity.MlmdEvaluate.Version == nil { + break } - ec.deferredResults <- ds - }() -} -func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapSchema(parsedSchema), nil -} + return e.complexity.MlmdEvaluate.Version(childComplexity), true -func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil -} + case "MlmdMetrics.description": + if e.complexity.MlmdMetrics.Description == nil { + break + } -var sources = []*ast.Source{ - {Name: "../../api/graphql/schema.graphqls", Input: `type Artifact { - id: ID - typeId: ID! - uri: String! - state: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ArtifactType! - properties : [ArtifactProperty!] -} + return e.complexity.MlmdMetrics.Description(childComplexity), true -type ArtifactProperty { - artifactId: ID - name: String - isCustomProperty: Boolean! - propertyValue: Value! -} + case "MlmdMetrics.externalId": + if e.complexity.MlmdMetrics.ExternalID == nil { + break + } -type Context { - id: ID - typeId: ID! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ContextType! - parent: Context - children: [Context] - attributions: [Artifact!] - associations: [Execution!] - properties: [ContextProperty!] -} + return e.complexity.MlmdMetrics.ExternalID(childComplexity), true -type ContextProperty { - contextId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} + case "MlmdMetrics.id": + if e.complexity.MlmdMetrics.ID == nil { + break + } -type Event { - id: ID - artifactId: ID! - executionId: ID! - type: Int! - artifact: Artifact - execution: Execution - millisecondsSinceEpoch: Int! -} + return e.complexity.MlmdMetrics.ID(childComplexity), true -type EventPath { - eventId: ID! - isIndexStep: Int! - stepIndex: Int! - stepKey: String! -} + case "MlmdMetrics.name": + if e.complexity.MlmdMetrics.Name == nil { + break + } -type Execution { - id: ID - typeId: ID! - lastKnownState: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ExecutionType! - properties: [ExecutionProperty!] -} + return e.complexity.MlmdMetrics.Name(childComplexity), true -type ExecutionProperty { - executionId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} + case "MlmdMetrics.properties": + if e.complexity.MlmdMetrics.Properties == nil { + break + } -union Value = IntValue | DoubleValue | StringValue | BoolValue + return e.complexity.MlmdMetrics.Properties(childComplexity), true -type IntValue { - value: Int! -} + case "MlmdMetrics.typeKind": + if e.complexity.MlmdMetrics.TypeKind == nil { + break + } -type DoubleValue { - value: Float! -} + return e.complexity.MlmdMetrics.TypeKind(childComplexity), true -type StringValue { - value: String! -} + case "MlmdMetrics.version": + if e.complexity.MlmdMetrics.Version == nil { + break + } -type BoolValue { - value: Boolean! -} + return e.complexity.MlmdMetrics.Version(childComplexity), true -interface Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} + case "MlmdModel.description": + if e.complexity.MlmdModel.Description == nil { + break + } -type TypeProperty { - typeId: ID! - name: String! - dataType: Int! -} + return e.complexity.MlmdModel.Description(childComplexity), true -type ArtifactType implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} + case "MlmdModel.externalId": + if e.complexity.MlmdModel.ExternalID == nil { + break + } -type ContextType implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} + return e.complexity.MlmdModel.ExternalID(childComplexity), true -type ExecutionType implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} + case "MlmdModel.id": + if e.complexity.MlmdModel.ID == nil { + break + } -input TypeFilter { - ids: [ID!] - names: [String!] - versions: [String!] - externalIds: [String!] -} + return e.complexity.MlmdModel.ID(childComplexity), true -input InstanceFilter { - ids: [ID!] - typeIds: [ID!] - names: [String!] - externalIds: [String!] -} + case "MlmdModel.name": + if e.complexity.MlmdModel.Name == nil { + break + } -type Query { - types(filter: TypeFilter): [Type!] - artifactTypes(filter: TypeFilter): [ArtifactType!] - contextTypes(filter: TypeFilter): [ContextType!] - executionTypes(filter: TypeFilter): [ExecutionType!] - artifacts(filter: InstanceFilter): [Artifact!] - contexts(filter: InstanceFilter): [Context!] - executions(filter: InstanceFilter): [Execution!] - events: [Event!] -} -`, BuiltIn: false}, -} -var parsedSchema = gqlparser.MustLoadSchema(sources...) + return e.complexity.MlmdModel.Name(childComplexity), true -// endregion ************************** generated!.gotpl ************************** + case "MlmdModel.properties": + if e.complexity.MlmdModel.Properties == nil { + break + } -// region ***************************** args.gotpl ***************************** + return e.complexity.MlmdModel.Properties(childComplexity), true -func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 string - if tmp, ok := rawArgs["name"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) - arg0, err = ec.unmarshalNString2string(ctx, tmp) - if err != nil { - return nil, err + case "MlmdModel.typeKind": + if e.complexity.MlmdModel.TypeKind == nil { + break } - } - args["name"] = arg0 - return args, nil -} -func (ec *executionContext) field_Query_artifactTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdModel.TypeKind(childComplexity), true + + case "MlmdModel.version": + if e.complexity.MlmdModel.Version == nil { + break } - } - args["filter"] = arg0 - return args, nil -} -func (ec *executionContext) field_Query_artifacts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdModel.Version(childComplexity), true + + case "MlmdProcess.description": + if e.complexity.MlmdProcess.Description == nil { + break } - } - args["filter"] = arg0 - return args, nil -} -func (ec *executionContext) field_Query_contextTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdProcess.Description(childComplexity), true + + case "MlmdProcess.externalId": + if e.complexity.MlmdProcess.ExternalID == nil { + break } - } - args["filter"] = arg0 - return args, nil -} -func (ec *executionContext) field_Query_contexts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdProcess.ExternalID(childComplexity), true + + case "MlmdProcess.id": + if e.complexity.MlmdProcess.ID == nil { + break } - } - args["filter"] = arg0 - return args, nil -} -func (ec *executionContext) field_Query_executionTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdProcess.ID(childComplexity), true + + case "MlmdProcess.inputType": + if e.complexity.MlmdProcess.InputType == nil { + break } - } - args["filter"] = arg0 - return args, nil -} -func (ec *executionContext) field_Query_executions_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdProcess.InputType(childComplexity), true + + case "MlmdProcess.name": + if e.complexity.MlmdProcess.Name == nil { + break } - } - args["filter"] = arg0 - return args, nil -} -func (ec *executionContext) field_Query_types_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdProcess.Name(childComplexity), true + + case "MlmdProcess.outputType": + if e.complexity.MlmdProcess.OutputType == nil { + break } - } - args["filter"] = arg0 - return args, nil -} -func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 bool - if tmp, ok := rawArgs["includeDeprecated"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) - arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdProcess.OutputType(childComplexity), true + + case "MlmdProcess.properties": + if e.complexity.MlmdProcess.Properties == nil { + break } - } - args["includeDeprecated"] = arg0 - return args, nil -} -func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 bool - if tmp, ok := rawArgs["includeDeprecated"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) - arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) - if err != nil { - return nil, err + return e.complexity.MlmdProcess.Properties(childComplexity), true + + case "MlmdProcess.typeKind": + if e.complexity.MlmdProcess.TypeKind == nil { + break } - } - args["includeDeprecated"] = arg0 - return args, nil -} -// endregion ***************************** args.gotpl ***************************** + return e.complexity.MlmdProcess.TypeKind(childComplexity), true -// region ************************** directives.gotpl ************************** + case "MlmdProcess.version": + if e.complexity.MlmdProcess.Version == nil { + break + } -// endregion ************************** directives.gotpl ************************** + return e.complexity.MlmdProcess.Version(childComplexity), true -// region **************************** field.gotpl ***************************** + case "MlmdStatistics.description": + if e.complexity.MlmdStatistics.Description == nil { + break + } -func (ec *executionContext) _Artifact_id(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + return e.complexity.MlmdStatistics.Description(childComplexity), true + + case "MlmdStatistics.externalId": + if e.complexity.MlmdStatistics.ExternalID == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdStatistics.ExternalID(childComplexity), true -func (ec *executionContext) _Artifact_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_typeId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdStatistics.id": + if e.complexity.MlmdStatistics.ID == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdStatistics.ID(childComplexity), true + + case "MlmdStatistics.name": + if e.complexity.MlmdStatistics.Name == nil { + break } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdStatistics.Name(childComplexity), true -func (ec *executionContext) _Artifact_uri(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_uri(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdStatistics.properties": + if e.complexity.MlmdStatistics.Properties == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.URI, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdStatistics.Properties(childComplexity), true + + case "MlmdStatistics.typeKind": + if e.complexity.MlmdStatistics.TypeKind == nil { + break } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_uri(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdStatistics.TypeKind(childComplexity), true -func (ec *executionContext) _Artifact_state(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_state(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdStatistics.version": + if e.complexity.MlmdStatistics.Version == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.State, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdStatistics.Version(childComplexity), true + + case "MlmdTrain.description": + if e.complexity.MlmdTrain.Description == nil { + break } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_state(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTrain.Description(childComplexity), true -func (ec *executionContext) _Artifact_name(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTrain.externalId": + if e.complexity.MlmdTrain.ExternalID == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdTrain.ExternalID(childComplexity), true + + case "MlmdTrain.id": + if e.complexity.MlmdTrain.ID == nil { + break } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTrain.ID(childComplexity), true -func (ec *executionContext) _Artifact_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTrain.inputType": + if e.complexity.MlmdTrain.InputType == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTrain.InputType(childComplexity), true -func (ec *executionContext) _Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTrain.name": + if e.complexity.MlmdTrain.Name == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.CreateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdTrain.Name(childComplexity), true + + case "MlmdTrain.outputType": + if e.complexity.MlmdTrain.OutputType == nil { + break } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTrain.OutputType(childComplexity), true -func (ec *executionContext) _Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTrain.properties": + if e.complexity.MlmdTrain.Properties == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.LastUpdateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdTrain.Properties(childComplexity), true + + case "MlmdTrain.typeKind": + if e.complexity.MlmdTrain.TypeKind == nil { + break } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTrain.TypeKind(childComplexity), true -func (ec *executionContext) _Artifact_type(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTrain.version": + if e.complexity.MlmdTrain.Version == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Artifact().Type(rctx, obj) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdTrain.Version(childComplexity), true + + case "MlmdTransform.description": + if e.complexity.MlmdTransform.Description == nil { + break } - return graphql.Null - } - res := resTmp.(*graph.ArtifactType) - fc.Result = res - return ec.marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ArtifactType_id(ctx, field) - case "name": - return ec.fieldContext_ArtifactType_name(ctx, field) - case "version": - return ec.fieldContext_ArtifactType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ArtifactType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ArtifactType_description(ctx, field) - case "externalId": - return ec.fieldContext_ArtifactType_externalId(ctx, field) - case "properties": - return ec.fieldContext_ArtifactType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ArtifactType", field.Name) - }, - } - return fc, nil -} + return e.complexity.MlmdTransform.Description(childComplexity), true -func (ec *executionContext) _Artifact_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTransform.externalId": + if e.complexity.MlmdTransform.ExternalID == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.ArtifactProperty) - fc.Result = res - return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Artifact_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "artifactId": - return ec.fieldContext_ArtifactProperty_artifactId(ctx, field) - case "name": - return ec.fieldContext_ArtifactProperty_name(ctx, field) - case "isCustomProperty": - return ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) - case "propertyValue": - return ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ArtifactProperty", field.Name) - }, - } - return fc, nil -} + return e.complexity.MlmdTransform.ExternalID(childComplexity), true -func (ec *executionContext) _ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_artifactId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTransform.id": + if e.complexity.MlmdTransform.ID == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ArtifactID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTransform.ID(childComplexity), true -func (ec *executionContext) _ArtifactProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTransform.inputType": + if e.complexity.MlmdTransform.InputType == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTransform.InputType(childComplexity), true -func (ec *executionContext) _ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTransform.name": + if e.complexity.MlmdTransform.Name == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsCustomProperty, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdTransform.Name(childComplexity), true + + case "MlmdTransform.outputType": + if e.complexity.MlmdTransform.OutputType == nil { + break } - return graphql.Null - } - res := resTmp.(bool) - fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTransform.OutputType(childComplexity), true -func (ec *executionContext) _ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTransform.properties": + if e.complexity.MlmdTransform.Properties == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.PropertyValue, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.MlmdTransform.Properties(childComplexity), true + + case "MlmdTransform.typeKind": + if e.complexity.MlmdTransform.TypeKind == nil { + break } - return graphql.Null - } - res := resTmp.(graph.Value) - fc.Result = res - return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Value does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTransform.TypeKind(childComplexity), true -func (ec *executionContext) _ArtifactType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "MlmdTransform.version": + if e.complexity.MlmdTransform.Version == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} + return e.complexity.MlmdTransform.Version(childComplexity), true -func (ec *executionContext) _ArtifactType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "Query.artifactTypes": + if e.complexity.Query.ArtifactTypes == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + args, err := ec.field_Query_artifactTypes_args(context.TODO(), rawArgs) + if err != nil { + return 0, false } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.Query.ArtifactTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true -func (ec *executionContext) _ArtifactType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "Query.artifacts": + if e.complexity.Query.Artifacts == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + args, err := ec.field_Query_artifacts_args(context.TODO(), rawArgs) + if err != nil { + return 0, false } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.Query.Artifacts(childComplexity, args["filter"].(*graph.InstanceFilter)), true -func (ec *executionContext) _ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "Query.contextTypes": + if e.complexity.Query.ContextTypes == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + args, err := ec.field_Query_contextTypes_args(context.TODO(), rawArgs) + if err != nil { + return 0, false } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} + return e.complexity.Query.ContextTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true -func (ec *executionContext) _ArtifactType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "Query.contexts": + if e.complexity.Query.Contexts == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + args, err := ec.field_Query_contexts_args(context.TODO(), rawArgs) + if err != nil { + return 0, false } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.Query.Contexts(childComplexity, args["filter"].(*graph.InstanceFilter)), true -func (ec *executionContext) _ArtifactType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "Query.events": + if e.complexity.Query.Events == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.Query.Events(childComplexity), true -func (ec *executionContext) _ArtifactType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "Query.executionTypes": + if e.complexity.Query.ExecutionTypes == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_ArtifactType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} + args, err := ec.field_Query_executionTypes_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } -func (ec *executionContext) _BoolValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.BoolValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_BoolValue_value(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + return e.complexity.Query.ExecutionTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true + + case "Query.executions": + if e.complexity.Query.Executions == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Value, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + args, err := ec.field_Query_executions_args(context.TODO(), rawArgs) + if err != nil { + return 0, false } - return graphql.Null - } - res := resTmp.(bool) - fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_BoolValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "BoolValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - return fc, nil -} + return e.complexity.Query.Executions(childComplexity, args["filter"].(*graph.InstanceFilter)), true -func (ec *executionContext) _Context_id(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "Query.mlmdDataset": + if e.complexity.Query.MlmdDataset == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Context_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} + args, err := ec.field_Query_mlmdDataset_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } -func (ec *executionContext) _Context_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_typeId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + return e.complexity.Query.MlmdDataset(childComplexity, args["filter"].(*graph.InstanceFilter)), true + + case "Query.types": + if e.complexity.Query.Types == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + args, err := ec.field_Query_types_args(context.TODO(), rawArgs) + if err != nil { + return 0, false } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Context_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} + return e.complexity.Query.Types(childComplexity, args["filter"].(*graph.TypeFilter)), true -func (ec *executionContext) _Context_name(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "StringValue.value": + if e.complexity.StringValue.Value == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + + return e.complexity.StringValue.Value(childComplexity), true + + case "TypeProperty.dataType": + if e.complexity.TypeProperty.DataType == nil { + break } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Context_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.TypeProperty.DataType(childComplexity), true -func (ec *executionContext) _Context_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "TypeProperty.name": + if e.complexity.TypeProperty.Name == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext_Context_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} + return e.complexity.TypeProperty.Name(childComplexity), true -func (ec *executionContext) _Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "TypeProperty.typeId": + if e.complexity.TypeProperty.TypeID == nil { + break } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.CreateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null + + return e.complexity.TypeProperty.TypeID(childComplexity), true + } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return 0, false } -func (ec *executionContext) fieldContext_Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} +func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { + rc := graphql.GetOperationContext(ctx) + ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)} + inputUnmarshalMap := graphql.BuildUnmarshalerMap( + ec.unmarshalInputInstanceFilter, + ec.unmarshalInputTypeFilter, + ) + first := true -func (ec *executionContext) _Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.LastUpdateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + switch rc.Operation.Operation { + case ast.Query: + return func(ctx context.Context) *graphql.Response { + var response graphql.Response + var data graphql.Marshaler + if first { + first = false + ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) + data = ec._Query(ctx, rc.Operation.SelectionSet) + } else { + if atomic.LoadInt32(&ec.pendingDeferred) > 0 { + result := <-ec.deferredResults + atomic.AddInt32(&ec.pendingDeferred, -1) + data = result.Result + response.Path = result.Path + response.Label = result.Label + response.Errors = result.Errors + } else { + return nil + } + } + var buf bytes.Buffer + data.MarshalGQL(&buf) + response.Data = buf.Bytes() + if atomic.LoadInt32(&ec.deferred) > 0 { + hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 + response.HasNext = &hasNext + } + + return &response } - return graphql.Null + + default: + return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil +type executionContext struct { + *graphql.OperationContext + *executableSchema + deferred int32 + pendingDeferred int32 + deferredResults chan graphql.DeferredResult } -func (ec *executionContext) _Context_type(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null +func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { + atomic.AddInt32(&ec.pendingDeferred, 1) + go func() { + ctx := graphql.WithFreshResponseContext(dg.Context) + dg.FieldSet.Dispatch(ctx) + ds := graphql.DeferredResult{ + Path: dg.Path, + Label: dg.Label, + Result: dg.FieldSet, + Errors: graphql.GetErrors(ctx), } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Type, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") + // null fields should bubble up + if dg.FieldSet.Invalids > 0 { + ds.Result = graphql.Null } - return graphql.Null - } - res := resTmp.(*graph.ContextType) - fc.Result = res - return ec.marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) + ec.deferredResults <- ds + }() } -func (ec *executionContext) fieldContext_Context_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ContextType_id(ctx, field) - case "name": - return ec.fieldContext_ContextType_name(ctx, field) - case "version": - return ec.fieldContext_ContextType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ContextType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ContextType_description(ctx, field) - case "externalId": - return ec.fieldContext_ContextType_externalId(ctx, field) - case "properties": - return ec.fieldContext_ContextType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ContextType", field.Name) - }, +func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") } - return fc, nil + return introspection.WrapSchema(parsedSchema), nil } -func (ec *executionContext) _Context_parent(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_parent(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Parent, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null +func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { + if ec.DisableIntrospection { + return nil, errors.New("introspection disabled") } - res := resTmp.(*graph.Context) - fc.Result = res - return ec.marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil } -func (ec *executionContext) fieldContext_Context_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Context_id(ctx, field) - case "typeId": - return ec.fieldContext_Context_typeId(ctx, field) - case "name": - return ec.fieldContext_Context_name(ctx, field) - case "externalId": - return ec.fieldContext_Context_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Context_type(ctx, field) - case "parent": - return ec.fieldContext_Context_parent(ctx, field) - case "children": - return ec.fieldContext_Context_children(ctx, field) - case "attributions": - return ec.fieldContext_Context_attributions(ctx, field) - case "associations": - return ec.fieldContext_Context_associations(ctx, field) - case "properties": - return ec.fieldContext_Context_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) - }, - } - return fc, nil +var sources = []*ast.Source{ + {Name: "../../api/graphql/base-schema.graphqls", Input: `type Artifact { + id: ID + typeId: ID! + uri: String! + state: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type(filter: InstanceFilter): ArtifactType! + properties : [ArtifactProperty!] } -func (ec *executionContext) _Context_children(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_children(ctx, field) - if err != nil { - return graphql.Null - } +type ArtifactProperty { + artifactId: ID + name: String + isCustomProperty: Boolean! + propertyValue: Value! +} + +type Context { + id: ID + typeId: ID! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ContextType! + parent: Context + children: [Context] + attributions: [Artifact!] + associations: [Execution!] + properties: [ContextProperty!] +} + +type ContextProperty { + contextId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +type Event { + id: ID + artifactId: ID! + executionId: ID! + type: Int! + artifact: Artifact + execution: Execution + millisecondsSinceEpoch: Int! +} + +type EventPath { + eventId: ID! + isIndexStep: Int! + stepIndex: Int! + stepKey: String! +} + +type Execution { + id: ID + typeId: ID! + lastKnownState: Int! + name: String! + externalId: String + createTimeSinceEpoch: Int! + lastUpdateTimeSinceEpoch: Int! + type: ExecutionType! + properties: [ExecutionProperty!] +} + +type ExecutionProperty { + executionId: ID + name: String! + isCustomProperty: Int! + propertyValue: Value! +} + +union Value = IntValue | DoubleValue | StringValue | BoolValue + +type IntValue { + value: Int! +} + +type DoubleValue { + value: Float! +} + +type StringValue { + value: String! +} + +type BoolValue { + value: Boolean! +} + +interface Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type TypeProperty { + typeId: ID! + name: String! + dataType: Int! +} + +interface ArtifactTypeInterface implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ArtifactType implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +interface ContextTypeInterface implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type ContextType implements ContextTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +interface ExecutionTypeInterface implements Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type ExecutionType implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} +`, BuiltIn: false}, + {Name: "../../api/graphql/ml-metadata.graphqls", Input: `type MlmdDataset implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdModel implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdMetrics implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdStatistics implements ArtifactTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + properties: [TypeProperty!] +} + +type MlmdTrain implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdTransform implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdProcess implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdEvaluate implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} + +type MlmdDeploy implements ExecutionTypeInterface & Type { + id: ID + name: String! + version: String! + typeKind: Int! + description: String! + externalId: String + inputType: String! + outputType: String! + properties: [TypeProperty!] +} +`, BuiltIn: false}, + {Name: "../../api/graphql/schema.graphqls", Input: `input TypeFilter { + ids: [ID!] + names: [String!] + versions: [String!] + externalIds: [String!] +} + +input InstanceFilter { + ids: [ID!] + typeIds: [ID!] + names: [String!] + externalIds: [String!] +} + +type Query { + types(filter: TypeFilter): [Type!] + artifactTypes(filter: TypeFilter): [ArtifactType!] + contextTypes(filter: TypeFilter): [ContextType!] + executionTypes(filter: TypeFilter): [ExecutionType!] + artifacts(filter: InstanceFilter): [Artifact!] + contexts(filter: InstanceFilter): [Context!] + executions(filter: InstanceFilter): [Execution!] + events: [Event!] + mlmdDataset(filter: InstanceFilter): [MlmdDataset!] +} +`, BuiltIn: false}, +} +var parsedSchema = gqlparser.MustLoadSchema(sources...) + +// endregion ************************** generated!.gotpl ************************** + +// region ***************************** args.gotpl ***************************** + +func (ec *executionContext) field_Artifact_type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["name"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["name"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_artifactTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_artifacts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_contextTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_contexts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_executionTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_executions_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_mlmdDataset_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.InstanceFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_types_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *graph.TypeFilter + if tmp, ok := rawArgs["filter"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + if err != nil { + return nil, err + } + } + args["filter"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := rawArgs["includeDeprecated"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["includeDeprecated"] = arg0 + return args, nil +} + +func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := rawArgs["includeDeprecated"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) + arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["includeDeprecated"] = arg0 + return args, nil +} + +// endregion ***************************** args.gotpl ***************************** + +// region ************************** directives.gotpl ************************** + +// endregion ************************** directives.gotpl ************************** + +// region **************************** field.gotpl ***************************** + +func (ec *executionContext) _Artifact_id(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_typeId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_uri(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_uri(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.URI, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_uri(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_state(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_state(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.State, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_state(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_name(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastUpdateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Artifact_type(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Artifact().Type(rctx, obj, fc.Args["filter"].(*graph.InstanceFilter)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*graph.ArtifactType) + fc.Result = res + return ec.marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ArtifactType_id(ctx, field) + case "name": + return ec.fieldContext_ArtifactType_name(ctx, field) + case "version": + return ec.fieldContext_ArtifactType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ArtifactType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ArtifactType_description(ctx, field) + case "externalId": + return ec.fieldContext_ArtifactType_externalId(ctx, field) + case "properties": + return ec.fieldContext_ArtifactType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ArtifactType", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Artifact_type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Artifact_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Artifact_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ArtifactProperty) + fc.Result = res + return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Artifact_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Artifact", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "artifactId": + return ec.fieldContext_ArtifactProperty_artifactId(ctx, field) + case "name": + return ec.fieldContext_ArtifactProperty_name(ctx, field) + case "isCustomProperty": + return ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) + case "propertyValue": + return ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ArtifactProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_artifactId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ArtifactID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsCustomProperty, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PropertyValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(graph.Value) + fc.Result = res + return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Value does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ArtifactType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ArtifactType_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ArtifactType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ArtifactType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _BoolValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.BoolValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_BoolValue_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_BoolValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "BoolValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_id(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_typeId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_name(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastUpdateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_type(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*graph.ContextType) + fc.Result = res + return ec.marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ContextType_id(ctx, field) + case "name": + return ec.fieldContext_ContextType_name(ctx, field) + case "version": + return ec.fieldContext_ContextType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ContextType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ContextType_description(ctx, field) + case "externalId": + return ec.fieldContext_ContextType_externalId(ctx, field) + case "properties": + return ec.fieldContext_ContextType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ContextType", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_parent(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_parent(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Parent, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graph.Context) + fc.Result = res + return ec.marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Context_id(ctx, field) + case "typeId": + return ec.fieldContext_Context_typeId(ctx, field) + case "name": + return ec.fieldContext_Context_name(ctx, field) + case "externalId": + return ec.fieldContext_Context_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Context_type(ctx, field) + case "parent": + return ec.fieldContext_Context_parent(ctx, field) + case "children": + return ec.fieldContext_Context_children(ctx, field) + case "attributions": + return ec.fieldContext_Context_attributions(ctx, field) + case "associations": + return ec.fieldContext_Context_associations(ctx, field) + case "properties": + return ec.fieldContext_Context_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_children(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_children(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Children, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Context) + fc.Result = res + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_children(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Context_id(ctx, field) + case "typeId": + return ec.fieldContext_Context_typeId(ctx, field) + case "name": + return ec.fieldContext_Context_name(ctx, field) + case "externalId": + return ec.fieldContext_Context_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Context_type(ctx, field) + case "parent": + return ec.fieldContext_Context_parent(ctx, field) + case "children": + return ec.fieldContext_Context_children(ctx, field) + case "attributions": + return ec.fieldContext_Context_attributions(ctx, field) + case "associations": + return ec.fieldContext_Context_associations(ctx, field) + case "properties": + return ec.fieldContext_Context_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_attributions(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_attributions(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Attributions, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Artifact) + fc.Result = res + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_attributions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Artifact_id(ctx, field) + case "typeId": + return ec.fieldContext_Artifact_typeId(ctx, field) + case "uri": + return ec.fieldContext_Artifact_uri(ctx, field) + case "state": + return ec.fieldContext_Artifact_state(ctx, field) + case "name": + return ec.fieldContext_Artifact_name(ctx, field) + case "externalId": + return ec.fieldContext_Artifact_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Artifact_type(ctx, field) + case "properties": + return ec.fieldContext_Artifact_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_associations(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_associations(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Associations, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Execution) + fc.Result = res + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_associations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Execution_id(ctx, field) + case "typeId": + return ec.fieldContext_Execution_typeId(ctx, field) + case "lastKnownState": + return ec.fieldContext_Execution_lastKnownState(ctx, field) + case "name": + return ec.fieldContext_Execution_name(ctx, field) + case "externalId": + return ec.fieldContext_Execution_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Execution_type(ctx, field) + case "properties": + return ec.fieldContext_Execution_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Context_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Context_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ContextProperty) + fc.Result = res + return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Context_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Context", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "contextId": + return ec.fieldContext_ContextProperty_contextId(ctx, field) + case "name": + return ec.fieldContext_ContextProperty_name(ctx, field) + case "isCustomProperty": + return ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) + case "propertyValue": + return ec.fieldContext_ContextProperty_propertyValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ContextProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_contextId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_contextId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ContextID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_contextId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsCustomProperty, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextProperty_propertyValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PropertyValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(graph.Value) + fc.Result = res + return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Value does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ContextType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ContextType_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ContextType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _DoubleValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.DoubleValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DoubleValue_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(float64) + fc.Result = res + return ec.marshalNFloat2float64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DoubleValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DoubleValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_id(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_artifactId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ArtifactID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_executionId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExecutionID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_type(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_artifact(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Artifact, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graph.Artifact) + fc.Result = res + return ec.marshalOArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_artifact(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Artifact_id(ctx, field) + case "typeId": + return ec.fieldContext_Artifact_typeId(ctx, field) + case "uri": + return ec.fieldContext_Artifact_uri(ctx, field) + case "state": + return ec.fieldContext_Artifact_state(ctx, field) + case "name": + return ec.fieldContext_Artifact_name(ctx, field) + case "externalId": + return ec.fieldContext_Artifact_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Artifact_type(ctx, field) + case "properties": + return ec.fieldContext_Artifact_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_execution(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_execution(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Execution, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*graph.Execution) + fc.Result = res + return ec.marshalOExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_execution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Execution_id(ctx, field) + case "typeId": + return ec.fieldContext_Execution_typeId(ctx, field) + case "lastKnownState": + return ec.fieldContext_Execution_lastKnownState(ctx, field) + case "name": + return ec.fieldContext_Execution_name(ctx, field) + case "externalId": + return ec.fieldContext_Execution_externalId(ctx, field) + case "createTimeSinceEpoch": + return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) + case "lastUpdateTimeSinceEpoch": + return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) + case "type": + return ec.fieldContext_Execution_type(ctx, field) + case "properties": + return ec.fieldContext_Execution_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.MillisecondsSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Event", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_eventId(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_eventId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.EventID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_eventId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_isIndexStep(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsIndexStep, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_stepIndex(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_stepIndex(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.StepIndex, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_stepIndex(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _EventPath_stepKey(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_EventPath_stepKey(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.StepKey, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_EventPath_stepKey(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "EventPath", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_id(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_typeId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNID2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_lastKnownState(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_lastKnownState(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastKnownState, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_lastKnownState(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_name(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.CreateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.LastUpdateTimeSinceEpoch, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_type(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Type, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*graph.ExecutionType) + fc.Result = res + return ec.marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_ExecutionType_id(ctx, field) + case "name": + return ec.fieldContext_ExecutionType_name(ctx, field) + case "version": + return ec.fieldContext_ExecutionType_version(ctx, field) + case "typeKind": + return ec.fieldContext_ExecutionType_typeKind(ctx, field) + case "description": + return ec.fieldContext_ExecutionType_description(ctx, field) + case "externalId": + return ec.fieldContext_ExecutionType_externalId(ctx, field) + case "inputType": + return ec.fieldContext_ExecutionType_inputType(ctx, field) + case "outputType": + return ec.fieldContext_ExecutionType_outputType(ctx, field) + case "properties": + return ec.fieldContext_ExecutionType_properties(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ExecutionType", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _Execution_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Execution_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.ExecutionProperty) + fc.Result = res + return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Execution_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Execution", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "executionId": + return ec.fieldContext_ExecutionProperty_executionId(ctx, field) + case "name": + return ec.fieldContext_ExecutionProperty_name(ctx, field) + case "isCustomProperty": + return ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) + case "propertyValue": + return ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type ExecutionProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_executionId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExecutionID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsCustomProperty, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.PropertyValue, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(graph.Value) + fc.Result = res + return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionProperty", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Value does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_inputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_outputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.OutputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_ExecutionType_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ExecutionType", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _IntValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.IntValue) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_IntValue_value(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Value, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_IntValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "IntValue", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDataset_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDataset_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDataset_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDataset", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDataset_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDataset_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDataset_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDataset", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDataset_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDataset_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDataset_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDataset", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDataset_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDataset_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDataset_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDataset", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDataset_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDataset_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDataset_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDataset", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDataset_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDataset_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDataset_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDataset", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDataset_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDataset_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDataset_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDataset", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_version(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Version, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_inputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_outputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.OutputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdDeploy_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdDeploy_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) + fc.Result = res + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdDeploy_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdDeploy", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_id(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type ID does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_version(ctx, field) + if err != nil { + return graphql.Null + } ctx = graphql.WithFieldContext(ctx, fc) defer func() { if r := recover(); r != nil { @@ -2699,61 +6602,304 @@ func (ec *executionContext) _Context_children(ctx context.Context, field graphql }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Children, nil + return obj.Version, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.([]*graph.Context) + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_typeKind(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.TypeKind, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Int does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_externalId(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.ExternalID, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_inputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.InputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_outputType(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.OutputType, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_MlmdEvaluate_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "MlmdEvaluate", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _MlmdEvaluate_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdEvaluate_properties(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Properties, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Context_children(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdEvaluate_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Context", + Object: "MlmdEvaluate", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "id": - return ec.fieldContext_Context_id(ctx, field) case "typeId": - return ec.fieldContext_Context_typeId(ctx, field) + return ec.fieldContext_TypeProperty_typeId(ctx, field) case "name": - return ec.fieldContext_Context_name(ctx, field) - case "externalId": - return ec.fieldContext_Context_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Context_type(ctx, field) - case "parent": - return ec.fieldContext_Context_parent(ctx, field) - case "children": - return ec.fieldContext_Context_children(ctx, field) - case "attributions": - return ec.fieldContext_Context_attributions(ctx, field) - case "associations": - return ec.fieldContext_Context_associations(ctx, field) - case "properties": - return ec.fieldContext_Context_properties(ctx, field) + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) }, } return fc, nil } -func (ec *executionContext) _Context_attributions(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_attributions(ctx, field) +func (ec *executionContext) _MlmdMetrics_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdMetrics_id(ctx, field) if err != nil { return graphql.Null } @@ -2766,7 +6912,7 @@ func (ec *executionContext) _Context_attributions(ctx context.Context, field gra }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Attributions, nil + return obj.ID, nil }) if err != nil { ec.Error(ctx, err) @@ -2775,48 +6921,26 @@ func (ec *executionContext) _Context_attributions(ctx context.Context, field gra if resTmp == nil { return graphql.Null } - res := resTmp.([]*graph.Artifact) + res := resTmp.(*string) fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Context_attributions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdMetrics_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Context", + Object: "MlmdMetrics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Artifact_id(ctx, field) - case "typeId": - return ec.fieldContext_Artifact_typeId(ctx, field) - case "uri": - return ec.fieldContext_Artifact_uri(ctx, field) - case "state": - return ec.fieldContext_Artifact_state(ctx, field) - case "name": - return ec.fieldContext_Artifact_name(ctx, field) - case "externalId": - return ec.fieldContext_Artifact_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Artifact_type(ctx, field) - case "properties": - return ec.fieldContext_Artifact_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) + return nil, errors.New("field of type ID does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Context_associations(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_associations(ctx, field) +func (ec *executionContext) _MlmdMetrics_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdMetrics_name(ctx, field) if err != nil { return graphql.Null } @@ -2829,55 +6953,38 @@ func (ec *executionContext) _Context_associations(ctx context.Context, field gra }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Associations, nil + return obj.Name, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.([]*graph.Execution) + res := resTmp.(string) fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Context_associations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdMetrics_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Context", + Object: "MlmdMetrics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Execution_id(ctx, field) - case "typeId": - return ec.fieldContext_Execution_typeId(ctx, field) - case "lastKnownState": - return ec.fieldContext_Execution_lastKnownState(ctx, field) - case "name": - return ec.fieldContext_Execution_name(ctx, field) - case "externalId": - return ec.fieldContext_Execution_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Execution_type(ctx, field) - case "properties": - return ec.fieldContext_Execution_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Context_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_properties(ctx, field) +func (ec *executionContext) _MlmdMetrics_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdMetrics_version(ctx, field) if err != nil { return graphql.Null } @@ -2890,45 +6997,38 @@ func (ec *executionContext) _Context_properties(ctx context.Context, field graph }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Properties, nil + return obj.Version, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.([]*graph.ContextProperty) + res := resTmp.(string) fc.Result = res - return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Context_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdMetrics_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Context", + Object: "MlmdMetrics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "contextId": - return ec.fieldContext_ContextProperty_contextId(ctx, field) - case "name": - return ec.fieldContext_ContextProperty_name(ctx, field) - case "isCustomProperty": - return ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) - case "propertyValue": - return ec.fieldContext_ContextProperty_propertyValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ContextProperty", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ContextProperty_contextId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_contextId(ctx, field) +func (ec *executionContext) _MlmdMetrics_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdMetrics_typeKind(ctx, field) if err != nil { return graphql.Null } @@ -2941,35 +7041,38 @@ func (ec *executionContext) _ContextProperty_contextId(ctx context.Context, fiel }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ContextID, nil + return obj.TypeKind, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*string) + res := resTmp.(int) fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextProperty_contextId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdMetrics_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextProperty", + Object: "MlmdMetrics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ContextProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_name(ctx, field) +func (ec *executionContext) _MlmdMetrics_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdMetrics_description(ctx, field) if err != nil { return graphql.Null } @@ -2982,7 +7085,7 @@ func (ec *executionContext) _ContextProperty_name(ctx context.Context, field gra }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Name, nil + return obj.Description, nil }) if err != nil { ec.Error(ctx, err) @@ -2999,9 +7102,9 @@ func (ec *executionContext) _ContextProperty_name(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdMetrics_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextProperty", + Object: "MlmdMetrics", Field: field, IsMethod: false, IsResolver: false, @@ -3012,8 +7115,8 @@ func (ec *executionContext) fieldContext_ContextProperty_name(ctx context.Contex return fc, nil } -func (ec *executionContext) _ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) +func (ec *executionContext) _MlmdMetrics_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdMetrics_externalId(ctx, field) if err != nil { return graphql.Null } @@ -3026,38 +7129,35 @@ func (ec *executionContext) _ContextProperty_isCustomProperty(ctx context.Contex }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.IsCustomProperty, nil + return obj.ExternalID, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(int) + res := resTmp.(*string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdMetrics_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextProperty", + Object: "MlmdMetrics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_propertyValue(ctx, field) +func (ec *executionContext) _MlmdMetrics_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdMetrics_properties(ctx, field) if err != nil { return graphql.Null } @@ -3070,38 +7170,43 @@ func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.PropertyValue, nil + return obj.Properties, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(graph.Value) + res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdMetrics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextProperty", + Object: "MlmdMetrics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Value does not have child fields") + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) }, } return fc, nil } -func (ec *executionContext) _ContextType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_id(ctx, field) +func (ec *executionContext) _MlmdModel_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdModel_id(ctx, field) if err != nil { return graphql.Null } @@ -3128,9 +7233,9 @@ func (ec *executionContext) _ContextType_id(ctx context.Context, field graphql.C return ec.marshalOID2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdModel_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextType", + Object: "MlmdModel", Field: field, IsMethod: false, IsResolver: false, @@ -3141,8 +7246,8 @@ func (ec *executionContext) fieldContext_ContextType_id(ctx context.Context, fie return fc, nil } -func (ec *executionContext) _ContextType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_name(ctx, field) +func (ec *executionContext) _MlmdModel_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdModel_name(ctx, field) if err != nil { return graphql.Null } @@ -3172,9 +7277,9 @@ func (ec *executionContext) _ContextType_name(ctx context.Context, field graphql return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdModel_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextType", + Object: "MlmdModel", Field: field, IsMethod: false, IsResolver: false, @@ -3185,8 +7290,8 @@ func (ec *executionContext) fieldContext_ContextType_name(ctx context.Context, f return fc, nil } -func (ec *executionContext) _ContextType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_version(ctx, field) +func (ec *executionContext) _MlmdModel_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdModel_version(ctx, field) if err != nil { return graphql.Null } @@ -3216,9 +7321,9 @@ func (ec *executionContext) _ContextType_version(ctx context.Context, field grap return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdModel_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextType", + Object: "MlmdModel", Field: field, IsMethod: false, IsResolver: false, @@ -3229,8 +7334,8 @@ func (ec *executionContext) fieldContext_ContextType_version(ctx context.Context return fc, nil } -func (ec *executionContext) _ContextType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_typeKind(ctx, field) +func (ec *executionContext) _MlmdModel_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdModel_typeKind(ctx, field) if err != nil { return graphql.Null } @@ -3260,9 +7365,9 @@ func (ec *executionContext) _ContextType_typeKind(ctx context.Context, field gra return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdModel_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextType", + Object: "MlmdModel", Field: field, IsMethod: false, IsResolver: false, @@ -3273,8 +7378,8 @@ func (ec *executionContext) fieldContext_ContextType_typeKind(ctx context.Contex return fc, nil } -func (ec *executionContext) _ContextType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_description(ctx, field) +func (ec *executionContext) _MlmdModel_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdModel_description(ctx, field) if err != nil { return graphql.Null } @@ -3304,9 +7409,9 @@ func (ec *executionContext) _ContextType_description(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdModel_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextType", + Object: "MlmdModel", Field: field, IsMethod: false, IsResolver: false, @@ -3317,8 +7422,8 @@ func (ec *executionContext) fieldContext_ContextType_description(ctx context.Con return fc, nil } -func (ec *executionContext) _ContextType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_externalId(ctx, field) +func (ec *executionContext) _MlmdModel_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdModel_externalId(ctx, field) if err != nil { return graphql.Null } @@ -3345,9 +7450,9 @@ func (ec *executionContext) _ContextType_externalId(ctx context.Context, field g return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdModel_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextType", + Object: "MlmdModel", Field: field, IsMethod: false, IsResolver: false, @@ -3358,8 +7463,8 @@ func (ec *executionContext) fieldContext_ContextType_externalId(ctx context.Cont return fc, nil } -func (ec *executionContext) _ContextType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_properties(ctx, field) +func (ec *executionContext) _MlmdModel_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdModel_properties(ctx, field) if err != nil { return graphql.Null } @@ -3386,9 +7491,9 @@ func (ec *executionContext) _ContextType_properties(ctx context.Context, field g return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdModel_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ContextType", + Object: "MlmdModel", Field: field, IsMethod: false, IsResolver: false, @@ -3407,8 +7512,8 @@ func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Cont return fc, nil } -func (ec *executionContext) _DoubleValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.DoubleValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_DoubleValue_value(ctx, field) +func (ec *executionContext) _MlmdProcess_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_id(ctx, field) if err != nil { return graphql.Null } @@ -3421,38 +7526,35 @@ func (ec *executionContext) _DoubleValue_value(ctx context.Context, field graphq }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Value, nil + return obj.ID, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(float64) + res := resTmp.(*string) fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_DoubleValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "DoubleValue", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") + return nil, errors.New("field of type ID does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Event_id(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_id(ctx, field) +func (ec *executionContext) _MlmdProcess_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_name(ctx, field) if err != nil { return graphql.Null } @@ -3465,35 +7567,38 @@ func (ec *executionContext) _Event_id(ctx context.Context, field graphql.Collect }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ID, nil + return obj.Name, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*string) + res := resTmp.(string) fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Event_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Event", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Event_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_artifactId(ctx, field) +func (ec *executionContext) _MlmdProcess_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_version(ctx, field) if err != nil { return graphql.Null } @@ -3506,7 +7611,7 @@ func (ec *executionContext) _Event_artifactId(ctx context.Context, field graphql }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ArtifactID, nil + return obj.Version, nil }) if err != nil { ec.Error(ctx, err) @@ -3520,24 +7625,24 @@ func (ec *executionContext) _Event_artifactId(ctx context.Context, field graphql } res := resTmp.(string) fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Event_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Event", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Event_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_executionId(ctx, field) +func (ec *executionContext) _MlmdProcess_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_typeKind(ctx, field) if err != nil { return graphql.Null } @@ -3550,7 +7655,7 @@ func (ec *executionContext) _Event_executionId(ctx context.Context, field graphq }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ExecutionID, nil + return obj.TypeKind, nil }) if err != nil { ec.Error(ctx, err) @@ -3562,26 +7667,26 @@ func (ec *executionContext) _Event_executionId(ctx context.Context, field graphq } return graphql.Null } - res := resTmp.(string) + res := resTmp.(int) fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Event_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Event", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Event_type(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_type(ctx, field) +func (ec *executionContext) _MlmdProcess_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_description(ctx, field) if err != nil { return graphql.Null } @@ -3594,7 +7699,7 @@ func (ec *executionContext) _Event_type(ctx context.Context, field graphql.Colle }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Type, nil + return obj.Description, nil }) if err != nil { ec.Error(ctx, err) @@ -3606,26 +7711,26 @@ func (ec *executionContext) _Event_type(ctx context.Context, field graphql.Colle } return graphql.Null } - res := resTmp.(int) + res := resTmp.(string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Event_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Event", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_artifact(ctx, field) +func (ec *executionContext) _MlmdProcess_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_externalId(ctx, field) if err != nil { return graphql.Null } @@ -3638,7 +7743,7 @@ func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Artifact, nil + return obj.ExternalID, nil }) if err != nil { ec.Error(ctx, err) @@ -3647,48 +7752,26 @@ func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.C if resTmp == nil { return graphql.Null } - res := resTmp.(*graph.Artifact) + res := resTmp.(*string) fc.Result = res - return ec.marshalOArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Event_artifact(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Event", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Artifact_id(ctx, field) - case "typeId": - return ec.fieldContext_Artifact_typeId(ctx, field) - case "uri": - return ec.fieldContext_Artifact_uri(ctx, field) - case "state": - return ec.fieldContext_Artifact_state(ctx, field) - case "name": - return ec.fieldContext_Artifact_name(ctx, field) - case "externalId": - return ec.fieldContext_Artifact_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Artifact_type(ctx, field) - case "properties": - return ec.fieldContext_Artifact_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Event_execution(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_execution(ctx, field) +func (ec *executionContext) _MlmdProcess_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_inputType(ctx, field) if err != nil { return graphql.Null } @@ -3701,55 +7784,38 @@ func (ec *executionContext) _Event_execution(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Execution, nil + return obj.InputType, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*graph.Execution) + res := resTmp.(string) fc.Result = res - return ec.marshalOExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Event_execution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Event", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Execution_id(ctx, field) - case "typeId": - return ec.fieldContext_Execution_typeId(ctx, field) - case "lastKnownState": - return ec.fieldContext_Execution_lastKnownState(ctx, field) - case "name": - return ec.fieldContext_Execution_name(ctx, field) - case "externalId": - return ec.fieldContext_Execution_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Execution_type(ctx, field) - case "properties": - return ec.fieldContext_Execution_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) +func (ec *executionContext) _MlmdProcess_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_outputType(ctx, field) if err != nil { return graphql.Null } @@ -3762,7 +7828,7 @@ func (ec *executionContext) _Event_millisecondsSinceEpoch(ctx context.Context, f }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.MillisecondsSinceEpoch, nil + return obj.OutputType, nil }) if err != nil { ec.Error(ctx, err) @@ -3774,26 +7840,26 @@ func (ec *executionContext) _Event_millisecondsSinceEpoch(ctx context.Context, f } return graphql.Null } - res := resTmp.(int) + res := resTmp.(string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Event", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _EventPath_eventId(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_eventId(ctx, field) +func (ec *executionContext) _MlmdProcess_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdProcess_properties(ctx, field) if err != nil { return graphql.Null } @@ -3806,38 +7872,43 @@ func (ec *executionContext) _EventPath_eventId(ctx context.Context, field graphq }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.EventID, nil + return obj.Properties, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(string) + res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_EventPath_eventId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdProcess_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "EventPath", + Object: "MlmdProcess", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) }, } return fc, nil } -func (ec *executionContext) _EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_isIndexStep(ctx, field) +func (ec *executionContext) _MlmdStatistics_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdStatistics_id(ctx, field) if err != nil { return graphql.Null } @@ -3850,38 +7921,35 @@ func (ec *executionContext) _EventPath_isIndexStep(ctx context.Context, field gr }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.IsIndexStep, nil + return obj.ID, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(int) + res := resTmp.(*string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdStatistics_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "EventPath", + Object: "MlmdStatistics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type ID does not have child fields") }, } return fc, nil } -func (ec *executionContext) _EventPath_stepIndex(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_stepIndex(ctx, field) +func (ec *executionContext) _MlmdStatistics_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdStatistics_name(ctx, field) if err != nil { return graphql.Null } @@ -3894,7 +7962,7 @@ func (ec *executionContext) _EventPath_stepIndex(ctx context.Context, field grap }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.StepIndex, nil + return obj.Name, nil }) if err != nil { ec.Error(ctx, err) @@ -3906,26 +7974,26 @@ func (ec *executionContext) _EventPath_stepIndex(ctx context.Context, field grap } return graphql.Null } - res := resTmp.(int) + res := resTmp.(string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_EventPath_stepIndex(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdStatistics_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "EventPath", + Object: "MlmdStatistics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _EventPath_stepKey(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_stepKey(ctx, field) +func (ec *executionContext) _MlmdStatistics_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdStatistics_version(ctx, field) if err != nil { return graphql.Null } @@ -3938,7 +8006,7 @@ func (ec *executionContext) _EventPath_stepKey(ctx context.Context, field graphq }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.StepKey, nil + return obj.Version, nil }) if err != nil { ec.Error(ctx, err) @@ -3955,9 +8023,9 @@ func (ec *executionContext) _EventPath_stepKey(ctx context.Context, field graphq return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_EventPath_stepKey(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdStatistics_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "EventPath", + Object: "MlmdStatistics", Field: field, IsMethod: false, IsResolver: false, @@ -3968,8 +8036,8 @@ func (ec *executionContext) fieldContext_EventPath_stepKey(ctx context.Context, return fc, nil } -func (ec *executionContext) _Execution_id(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_id(ctx, field) +func (ec *executionContext) _MlmdStatistics_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdStatistics_typeKind(ctx, field) if err != nil { return graphql.Null } @@ -3982,35 +8050,38 @@ func (ec *executionContext) _Execution_id(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ID, nil + return obj.TypeKind, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.(*string) + res := resTmp.(int) fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdStatistics_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdStatistics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Execution_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_typeId(ctx, field) +func (ec *executionContext) _MlmdStatistics_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdStatistics_description(ctx, field) if err != nil { return graphql.Null } @@ -4023,7 +8094,7 @@ func (ec *executionContext) _Execution_typeId(ctx context.Context, field graphql }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.TypeID, nil + return obj.Description, nil }) if err != nil { ec.Error(ctx, err) @@ -4037,24 +8108,24 @@ func (ec *executionContext) _Execution_typeId(ctx context.Context, field graphql } res := resTmp.(string) fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdStatistics_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdStatistics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Execution_lastKnownState(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_lastKnownState(ctx, field) +func (ec *executionContext) _MlmdStatistics_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdStatistics_externalId(ctx, field) if err != nil { return graphql.Null } @@ -4067,38 +8138,35 @@ func (ec *executionContext) _Execution_lastKnownState(ctx context.Context, field }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.LastKnownState, nil + return obj.ExternalID, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(int) + res := resTmp.(*string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_lastKnownState(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdStatistics_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdStatistics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Execution_name(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_name(ctx, field) +func (ec *executionContext) _MlmdStatistics_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdStatistics_properties(ctx, field) if err != nil { return graphql.Null } @@ -4111,38 +8179,43 @@ func (ec *executionContext) _Execution_name(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Name, nil + return obj.Properties, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(string) + res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdStatistics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdStatistics", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) }, } return fc, nil } -func (ec *executionContext) _Execution_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_externalId(ctx, field) +func (ec *executionContext) _MlmdTrain_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_id(ctx, field) if err != nil { return graphql.Null } @@ -4155,7 +8228,7 @@ func (ec *executionContext) _Execution_externalId(ctx context.Context, field gra }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil + return obj.ID, nil }) if err != nil { ec.Error(ctx, err) @@ -4166,24 +8239,24 @@ func (ec *executionContext) _Execution_externalId(ctx context.Context, field gra } res := resTmp.(*string) fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) + return ec.marshalOID2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") + return nil, errors.New("field of type ID does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) +func (ec *executionContext) _MlmdTrain_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_name(ctx, field) if err != nil { return graphql.Null } @@ -4196,7 +8269,7 @@ func (ec *executionContext) _Execution_createTimeSinceEpoch(ctx context.Context, }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.CreateTimeSinceEpoch, nil + return obj.Name, nil }) if err != nil { ec.Error(ctx, err) @@ -4208,26 +8281,26 @@ func (ec *executionContext) _Execution_createTimeSinceEpoch(ctx context.Context, } return graphql.Null } - res := resTmp.(int) + res := resTmp.(string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) +func (ec *executionContext) _MlmdTrain_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_version(ctx, field) if err != nil { return graphql.Null } @@ -4240,7 +8313,7 @@ func (ec *executionContext) _Execution_lastUpdateTimeSinceEpoch(ctx context.Cont }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.LastUpdateTimeSinceEpoch, nil + return obj.Version, nil }) if err != nil { ec.Error(ctx, err) @@ -4252,26 +8325,26 @@ func (ec *executionContext) _Execution_lastUpdateTimeSinceEpoch(ctx context.Cont } return graphql.Null } - res := resTmp.(int) + res := resTmp.(string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_type(ctx, field) +func (ec *executionContext) _MlmdTrain_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_typeKind(ctx, field) if err != nil { return graphql.Null } @@ -4284,7 +8357,7 @@ func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Type, nil + return obj.TypeKind, nil }) if err != nil { ec.Error(ctx, err) @@ -4296,46 +8369,26 @@ func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.C } return graphql.Null } - res := resTmp.(*graph.ExecutionType) + res := resTmp.(int) fc.Result = res - return ec.marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) + return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ExecutionType_id(ctx, field) - case "name": - return ec.fieldContext_ExecutionType_name(ctx, field) - case "version": - return ec.fieldContext_ExecutionType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ExecutionType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ExecutionType_description(ctx, field) - case "externalId": - return ec.fieldContext_ExecutionType_externalId(ctx, field) - case "inputType": - return ec.fieldContext_ExecutionType_inputType(ctx, field) - case "outputType": - return ec.fieldContext_ExecutionType_outputType(ctx, field) - case "properties": - return ec.fieldContext_ExecutionType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ExecutionType", field.Name) + return nil, errors.New("field of type Int does not have child fields") }, } return fc, nil } -func (ec *executionContext) _Execution_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_properties(ctx, field) +func (ec *executionContext) _MlmdTrain_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_description(ctx, field) if err != nil { return graphql.Null } @@ -4348,45 +8401,38 @@ func (ec *executionContext) _Execution_properties(ctx context.Context, field gra }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Properties, nil + return obj.Description, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } return graphql.Null } - res := resTmp.([]*graph.ExecutionProperty) + res := resTmp.(string) fc.Result = res - return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Execution_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "Execution", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "executionId": - return ec.fieldContext_ExecutionProperty_executionId(ctx, field) - case "name": - return ec.fieldContext_ExecutionProperty_name(ctx, field) - case "isCustomProperty": - return ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) - case "propertyValue": - return ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ExecutionProperty", field.Name) + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_executionId(ctx, field) +func (ec *executionContext) _MlmdTrain_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_externalId(ctx, field) if err != nil { return graphql.Null } @@ -4399,7 +8445,7 @@ func (ec *executionContext) _ExecutionProperty_executionId(ctx context.Context, }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.ExecutionID, nil + return obj.ExternalID, nil }) if err != nil { ec.Error(ctx, err) @@ -4410,24 +8456,24 @@ func (ec *executionContext) _ExecutionProperty_executionId(ctx context.Context, } res := resTmp.(*string) fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionProperty", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ExecutionProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_name(ctx, field) +func (ec *executionContext) _MlmdTrain_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_inputType(ctx, field) if err != nil { return graphql.Null } @@ -4440,7 +8486,7 @@ func (ec *executionContext) _ExecutionProperty_name(ctx context.Context, field g }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Name, nil + return obj.InputType, nil }) if err != nil { ec.Error(ctx, err) @@ -4457,9 +8503,9 @@ func (ec *executionContext) _ExecutionProperty_name(ctx context.Context, field g return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionProperty", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, @@ -4470,8 +8516,8 @@ func (ec *executionContext) fieldContext_ExecutionProperty_name(ctx context.Cont return fc, nil } -func (ec *executionContext) _ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) +func (ec *executionContext) _MlmdTrain_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_outputType(ctx, field) if err != nil { return graphql.Null } @@ -4484,7 +8530,7 @@ func (ec *executionContext) _ExecutionProperty_isCustomProperty(ctx context.Cont }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.IsCustomProperty, nil + return obj.OutputType, nil }) if err != nil { ec.Error(ctx, err) @@ -4496,26 +8542,26 @@ func (ec *executionContext) _ExecutionProperty_isCustomProperty(ctx context.Cont } return graphql.Null } - res := resTmp.(int) + res := resTmp.(string) fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) + return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionProperty", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") + return nil, errors.New("field of type String does not have child fields") }, } return fc, nil } -func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) +func (ec *executionContext) _MlmdTrain_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTrain_properties(ctx, field) if err != nil { return graphql.Null } @@ -4528,38 +8574,43 @@ func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.PropertyValue, nil + return obj.Properties, nil }) if err != nil { ec.Error(ctx, err) return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(graph.Value) + res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTrain_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionProperty", + Object: "MlmdTrain", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Value does not have child fields") + switch field.Name { + case "typeId": + return ec.fieldContext_TypeProperty_typeId(ctx, field) + case "name": + return ec.fieldContext_TypeProperty_name(ctx, field) + case "dataType": + return ec.fieldContext_TypeProperty_dataType(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) }, } return fc, nil } -func (ec *executionContext) _ExecutionType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_id(ctx, field) +func (ec *executionContext) _MlmdTransform_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_id(ctx, field) if err != nil { return graphql.Null } @@ -4586,9 +8637,9 @@ func (ec *executionContext) _ExecutionType_id(ctx context.Context, field graphql return ec.marshalOID2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4599,8 +8650,8 @@ func (ec *executionContext) fieldContext_ExecutionType_id(ctx context.Context, f return fc, nil } -func (ec *executionContext) _ExecutionType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_name(ctx, field) +func (ec *executionContext) _MlmdTransform_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_name(ctx, field) if err != nil { return graphql.Null } @@ -4630,9 +8681,9 @@ func (ec *executionContext) _ExecutionType_name(ctx context.Context, field graph return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4643,8 +8694,8 @@ func (ec *executionContext) fieldContext_ExecutionType_name(ctx context.Context, return fc, nil } -func (ec *executionContext) _ExecutionType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_version(ctx, field) +func (ec *executionContext) _MlmdTransform_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_version(ctx, field) if err != nil { return graphql.Null } @@ -4674,9 +8725,9 @@ func (ec *executionContext) _ExecutionType_version(ctx context.Context, field gr return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4687,8 +8738,8 @@ func (ec *executionContext) fieldContext_ExecutionType_version(ctx context.Conte return fc, nil } -func (ec *executionContext) _ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_typeKind(ctx, field) +func (ec *executionContext) _MlmdTransform_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_typeKind(ctx, field) if err != nil { return graphql.Null } @@ -4718,9 +8769,9 @@ func (ec *executionContext) _ExecutionType_typeKind(ctx context.Context, field g return ec.marshalNInt2int(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4731,8 +8782,8 @@ func (ec *executionContext) fieldContext_ExecutionType_typeKind(ctx context.Cont return fc, nil } -func (ec *executionContext) _ExecutionType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_description(ctx, field) +func (ec *executionContext) _MlmdTransform_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_description(ctx, field) if err != nil { return graphql.Null } @@ -4762,9 +8813,9 @@ func (ec *executionContext) _ExecutionType_description(ctx context.Context, fiel return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4775,8 +8826,8 @@ func (ec *executionContext) fieldContext_ExecutionType_description(ctx context.C return fc, nil } -func (ec *executionContext) _ExecutionType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_externalId(ctx, field) +func (ec *executionContext) _MlmdTransform_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_externalId(ctx, field) if err != nil { return graphql.Null } @@ -4803,9 +8854,9 @@ func (ec *executionContext) _ExecutionType_externalId(ctx context.Context, field return ec.marshalOString2ᚖstring(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4816,8 +8867,8 @@ func (ec *executionContext) fieldContext_ExecutionType_externalId(ctx context.Co return fc, nil } -func (ec *executionContext) _ExecutionType_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_inputType(ctx, field) +func (ec *executionContext) _MlmdTransform_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_inputType(ctx, field) if err != nil { return graphql.Null } @@ -4847,9 +8898,9 @@ func (ec *executionContext) _ExecutionType_inputType(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4860,8 +8911,8 @@ func (ec *executionContext) fieldContext_ExecutionType_inputType(ctx context.Con return fc, nil } -func (ec *executionContext) _ExecutionType_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_outputType(ctx, field) +func (ec *executionContext) _MlmdTransform_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_outputType(ctx, field) if err != nil { return graphql.Null } @@ -4891,9 +8942,9 @@ func (ec *executionContext) _ExecutionType_outputType(ctx context.Context, field return ec.marshalNString2string(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4904,8 +8955,8 @@ func (ec *executionContext) fieldContext_ExecutionType_outputType(ctx context.Co return fc, nil } -func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_properties(ctx, field) +func (ec *executionContext) _MlmdTransform_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_MlmdTransform_properties(ctx, field) if err != nil { return graphql.Null } @@ -4932,9 +8983,9 @@ func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_MlmdTransform_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "ExecutionType", + Object: "MlmdTransform", Field: field, IsMethod: false, IsResolver: false, @@ -4953,50 +9004,6 @@ func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Co return fc, nil } -func (ec *executionContext) _IntValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.IntValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_IntValue_value(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Value, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_IntValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "IntValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - func (ec *executionContext) _Query_types(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Query_types(ctx, field) if err != nil { @@ -5464,25 +9471,82 @@ func (ec *executionContext) fieldContext_Query_executions(ctx context.Context, f case "properties": return ec.fieldContext_Execution_properties(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_executions_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_events(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_events(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Events(rctx) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*graph.Event) + fc.Result = res + return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Event_id(ctx, field) + case "artifactId": + return ec.fieldContext_Event_artifactId(ctx, field) + case "executionId": + return ec.fieldContext_Event_executionId(ctx, field) + case "type": + return ec.fieldContext_Event_type(ctx, field) + case "artifact": + return ec.fieldContext_Event_artifact(ctx, field) + case "execution": + return ec.fieldContext_Event_execution(ctx, field) + case "millisecondsSinceEpoch": + return ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Event", field.Name) }, } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_executions_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } return fc, nil } -func (ec *executionContext) _Query_events(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_events(ctx, field) +func (ec *executionContext) _Query_mlmdDataset(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Query_mlmdDataset(ctx, field) if err != nil { return graphql.Null } @@ -5495,7 +9559,7 @@ func (ec *executionContext) _Query_events(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Events(rctx) + return ec.resolvers.Query().MlmdDataset(rctx, fc.Args["filter"].(*graph.InstanceFilter)) }) if err != nil { ec.Error(ctx, err) @@ -5504,12 +9568,12 @@ func (ec *executionContext) _Query_events(ctx context.Context, field graphql.Col if resTmp == nil { return graphql.Null } - res := resTmp.([]*graph.Event) + res := resTmp.([]*graph.MlmdDataset) fc.Result = res - return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) + return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_mlmdDataset(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -5518,23 +9582,34 @@ func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": - return ec.fieldContext_Event_id(ctx, field) - case "artifactId": - return ec.fieldContext_Event_artifactId(ctx, field) - case "executionId": - return ec.fieldContext_Event_executionId(ctx, field) - case "type": - return ec.fieldContext_Event_type(ctx, field) - case "artifact": - return ec.fieldContext_Event_artifact(ctx, field) - case "execution": - return ec.fieldContext_Event_execution(ctx, field) - case "millisecondsSinceEpoch": - return ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) + return ec.fieldContext_MlmdDataset_id(ctx, field) + case "name": + return ec.fieldContext_MlmdDataset_name(ctx, field) + case "version": + return ec.fieldContext_MlmdDataset_version(ctx, field) + case "typeKind": + return ec.fieldContext_MlmdDataset_typeKind(ctx, field) + case "description": + return ec.fieldContext_MlmdDataset_description(ctx, field) + case "externalId": + return ec.fieldContext_MlmdDataset_externalId(ctx, field) + case "properties": + return ec.fieldContext_MlmdDataset_properties(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type Event", field.Name) + return nil, fmt.Errorf("no field named %q was found under type MlmdDataset", field.Name) }, } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_mlmdDataset_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } return fc, nil } @@ -7121,8 +11196,219 @@ func (ec *executionContext) fieldContext___Type_kind(ctx context.Context, field return fc, nil } -func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_name(ctx, field) +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_name(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Name(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_description(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Description(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_fields(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + fc.Result = res + return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext___Field_name(ctx, field) + case "description": + return ec.fieldContext___Field_description(ctx, field) + case "args": + return ec.fieldContext___Field_args(ctx, field) + case "type": + return ec.fieldContext___Field_type(ctx, field) + case "isDeprecated": + return ec.fieldContext___Field_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___Field_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Type_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_interfaces(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Interfaces(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + fc.Result = res + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) if err != nil { return graphql.Null } @@ -7135,7 +11421,7 @@ func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.Coll }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Name(), nil + return obj.PossibleTypes(), nil }) if err != nil { ec.Error(ctx, err) @@ -7144,26 +11430,48 @@ func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.Coll if resTmp == nil { return graphql.Null } - res := resTmp.(*string) + res := resTmp.([]introspection.Type) fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) + return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, IsMethod: true, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") + switch field.Name { + case "kind": + return ec.fieldContext___Type_kind(ctx, field) + case "name": + return ec.fieldContext___Type_name(ctx, field) + case "description": + return ec.fieldContext___Type_description(ctx, field) + case "fields": + return ec.fieldContext___Type_fields(ctx, field) + case "interfaces": + return ec.fieldContext___Type_interfaces(ctx, field) + case "possibleTypes": + return ec.fieldContext___Type_possibleTypes(ctx, field) + case "enumValues": + return ec.fieldContext___Type_enumValues(ctx, field) + case "inputFields": + return ec.fieldContext___Type_inputFields(ctx, field) + case "ofType": + return ec.fieldContext___Type_ofType(ctx, field) + case "specifiedByURL": + return ec.fieldContext___Type_specifiedByURL(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) }, } return fc, nil } -func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_description(ctx, field) +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_enumValues(ctx, field) if err != nil { return graphql.Null } @@ -7176,7 +11484,7 @@ func (ec *executionContext) ___Type_description(ctx context.Context, field graph }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Description(), nil + return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil }) if err != nil { ec.Error(ctx, err) @@ -7185,26 +11493,47 @@ func (ec *executionContext) ___Type_description(ctx context.Context, field graph if resTmp == nil { return graphql.Null } - res := resTmp.(*string) + res := resTmp.([]introspection.EnumValue) fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) + return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, IsMethod: true, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") + switch field.Name { + case "name": + return ec.fieldContext___EnumValue_name(ctx, field) + case "description": + return ec.fieldContext___EnumValue_description(ctx, field) + case "isDeprecated": + return ec.fieldContext___EnumValue_isDeprecated(ctx, field) + case "deprecationReason": + return ec.fieldContext___EnumValue_deprecationReason(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) }, } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field___Type_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } return fc, nil } -func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_fields(ctx, field) +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_inputFields(ctx, field) if err != nil { return graphql.Null } @@ -7217,7 +11546,7 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil + return obj.InputFields(), nil }) if err != nil { ec.Error(ctx, err) @@ -7226,12 +11555,12 @@ func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.Co if resTmp == nil { return graphql.Null } - res := resTmp.([]introspection.Field) + res := resTmp.([]introspection.InputValue) fc.Result = res - return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) + return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -7240,37 +11569,22 @@ func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, fiel Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "name": - return ec.fieldContext___Field_name(ctx, field) + return ec.fieldContext___InputValue_name(ctx, field) case "description": - return ec.fieldContext___Field_description(ctx, field) - case "args": - return ec.fieldContext___Field_args(ctx, field) + return ec.fieldContext___InputValue_description(ctx, field) case "type": - return ec.fieldContext___Field_type(ctx, field) - case "isDeprecated": - return ec.fieldContext___Field_isDeprecated(ctx, field) - case "deprecationReason": - return ec.fieldContext___Field_deprecationReason(ctx, field) + return ec.fieldContext___InputValue_type(ctx, field) + case "defaultValue": + return ec.fieldContext___InputValue_defaultValue(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) + return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) }, } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field___Type_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } return fc, nil } -func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_interfaces(ctx, field) +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_ofType(ctx, field) if err != nil { return graphql.Null } @@ -7283,7 +11597,7 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.Interfaces(), nil + return obj.OfType(), nil }) if err != nil { ec.Error(ctx, err) @@ -7292,12 +11606,12 @@ func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphq if resTmp == nil { return graphql.Null } - res := resTmp.([]introspection.Type) + res := resTmp.(*introspection.Type) fc.Result = res - return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) + return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "__Type", Field: field, @@ -7326,566 +11640,946 @@ func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, case "specifiedByURL": return ec.fieldContext___Type_specifiedByURL(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, + return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) + }, + } + return fc, nil +} + +func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { + fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.SpecifiedByURL(), nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2ᚖstring(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "__Type", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputInstanceFilter(ctx context.Context, obj interface{}) (graph.InstanceFilter, error) { + var it graph.InstanceFilter + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"ids", "typeIds", "names", "externalIds"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "ids": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) + data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Ids = data + case "typeIds": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("typeIds")) + data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.TypeIds = data + case "names": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Names = data + case "externalIds": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.ExternalIds = data + } + } + + return it, nil +} + +func (ec *executionContext) unmarshalInputTypeFilter(ctx context.Context, obj interface{}) (graph.TypeFilter, error) { + var it graph.TypeFilter + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"ids", "names", "versions", "externalIds"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "ids": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) + data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Ids = data + case "names": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Names = data + case "versions": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("versions")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.Versions = data + case "externalIds": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.ExternalIds = data + } } - return fc, nil + + return it, nil } -func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) - if err != nil { +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +func (ec *executionContext) _ArtifactTypeInterface(ctx context.Context, sel ast.SelectionSet, obj graph.ArtifactTypeInterface) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case graph.ArtifactType: + return ec._ArtifactType(ctx, sel, &obj) + case *graph.ArtifactType: + if obj == nil { + return graphql.Null } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.PossibleTypes(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null + return ec._ArtifactType(ctx, sel, obj) + case graph.MlmdDataset: + return ec._MlmdDataset(ctx, sel, &obj) + case *graph.MlmdDataset: + if obj == nil { + return graphql.Null + } + return ec._MlmdDataset(ctx, sel, obj) + case graph.MlmdModel: + return ec._MlmdModel(ctx, sel, &obj) + case *graph.MlmdModel: + if obj == nil { + return graphql.Null + } + return ec._MlmdModel(ctx, sel, obj) + case graph.MlmdMetrics: + return ec._MlmdMetrics(ctx, sel, &obj) + case *graph.MlmdMetrics: + if obj == nil { + return graphql.Null + } + return ec._MlmdMetrics(ctx, sel, obj) + case graph.MlmdStatistics: + return ec._MlmdStatistics(ctx, sel, &obj) + case *graph.MlmdStatistics: + if obj == nil { + return graphql.Null + } + return ec._MlmdStatistics(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) } - res := resTmp.([]introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, +func (ec *executionContext) _ContextTypeInterface(ctx context.Context, sel ast.SelectionSet, obj graph.ContextTypeInterface) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case graph.ContextType: + return ec._ContextType(ctx, sel, &obj) + case *graph.ContextType: + if obj == nil { + return graphql.Null + } + return ec._ContextType(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) } - return fc, nil } -func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_enumValues(ctx, field) - if err != nil { +func (ec *executionContext) _ExecutionTypeInterface(ctx context.Context, sel ast.SelectionSet, obj graph.ExecutionTypeInterface) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case graph.ExecutionType: + return ec._ExecutionType(ctx, sel, &obj) + case *graph.ExecutionType: + if obj == nil { + return graphql.Null } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null + return ec._ExecutionType(ctx, sel, obj) + case graph.MlmdTrain: + return ec._MlmdTrain(ctx, sel, &obj) + case *graph.MlmdTrain: + if obj == nil { + return graphql.Null + } + return ec._MlmdTrain(ctx, sel, obj) + case graph.MlmdTransform: + return ec._MlmdTransform(ctx, sel, &obj) + case *graph.MlmdTransform: + if obj == nil { + return graphql.Null + } + return ec._MlmdTransform(ctx, sel, obj) + case graph.MlmdProcess: + return ec._MlmdProcess(ctx, sel, &obj) + case *graph.MlmdProcess: + if obj == nil { + return graphql.Null + } + return ec._MlmdProcess(ctx, sel, obj) + case graph.MlmdEvaluate: + return ec._MlmdEvaluate(ctx, sel, &obj) + case *graph.MlmdEvaluate: + if obj == nil { + return graphql.Null + } + return ec._MlmdEvaluate(ctx, sel, obj) + case graph.MlmdDeploy: + return ec._MlmdDeploy(ctx, sel, &obj) + case *graph.MlmdDeploy: + if obj == nil { + return graphql.Null + } + return ec._MlmdDeploy(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) } - res := resTmp.([]introspection.EnumValue) - fc.Result = res - return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___EnumValue_name(ctx, field) - case "description": - return ec.fieldContext___EnumValue_description(ctx, field) - case "isDeprecated": - return ec.fieldContext___EnumValue_isDeprecated(ctx, field) - case "deprecationReason": - return ec.fieldContext___EnumValue_deprecationReason(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) +func (ec *executionContext) _Type(ctx context.Context, sel ast.SelectionSet, obj graph.Type) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: + return graphql.Null + case graph.ArtifactTypeInterface: + if obj == nil { + return graphql.Null + } + return ec._ArtifactTypeInterface(ctx, sel, obj) + case graph.ArtifactType: + return ec._ArtifactType(ctx, sel, &obj) + case *graph.ArtifactType: + if obj == nil { + return graphql.Null + } + return ec._ArtifactType(ctx, sel, obj) + case graph.ContextTypeInterface: + if obj == nil { + return graphql.Null + } + return ec._ContextTypeInterface(ctx, sel, obj) + case graph.ContextType: + return ec._ContextType(ctx, sel, &obj) + case *graph.ContextType: + if obj == nil { + return graphql.Null + } + return ec._ContextType(ctx, sel, obj) + case graph.ExecutionTypeInterface: + if obj == nil { + return graphql.Null + } + return ec._ExecutionTypeInterface(ctx, sel, obj) + case graph.ExecutionType: + return ec._ExecutionType(ctx, sel, &obj) + case *graph.ExecutionType: + if obj == nil { + return graphql.Null + } + return ec._ExecutionType(ctx, sel, obj) + case graph.MlmdDataset: + return ec._MlmdDataset(ctx, sel, &obj) + case *graph.MlmdDataset: + if obj == nil { + return graphql.Null + } + return ec._MlmdDataset(ctx, sel, obj) + case graph.MlmdModel: + return ec._MlmdModel(ctx, sel, &obj) + case *graph.MlmdModel: + if obj == nil { + return graphql.Null + } + return ec._MlmdModel(ctx, sel, obj) + case graph.MlmdMetrics: + return ec._MlmdMetrics(ctx, sel, &obj) + case *graph.MlmdMetrics: + if obj == nil { + return graphql.Null + } + return ec._MlmdMetrics(ctx, sel, obj) + case graph.MlmdStatistics: + return ec._MlmdStatistics(ctx, sel, &obj) + case *graph.MlmdStatistics: + if obj == nil { + return graphql.Null + } + return ec._MlmdStatistics(ctx, sel, obj) + case graph.MlmdTrain: + return ec._MlmdTrain(ctx, sel, &obj) + case *graph.MlmdTrain: + if obj == nil { + return graphql.Null + } + return ec._MlmdTrain(ctx, sel, obj) + case graph.MlmdTransform: + return ec._MlmdTransform(ctx, sel, &obj) + case *graph.MlmdTransform: + if obj == nil { + return graphql.Null + } + return ec._MlmdTransform(ctx, sel, obj) + case graph.MlmdProcess: + return ec._MlmdProcess(ctx, sel, &obj) + case *graph.MlmdProcess: + if obj == nil { + return graphql.Null + } + return ec._MlmdProcess(ctx, sel, obj) + case graph.MlmdEvaluate: + return ec._MlmdEvaluate(ctx, sel, &obj) + case *graph.MlmdEvaluate: + if obj == nil { + return graphql.Null + } + return ec._MlmdEvaluate(ctx, sel, obj) + case graph.MlmdDeploy: + return ec._MlmdDeploy(ctx, sel, &obj) + case *graph.MlmdDeploy: + if obj == nil { + return graphql.Null } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field___Type_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err + return ec._MlmdDeploy(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) } - return fc, nil } -func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_inputFields(ctx, field) - if err != nil { +func (ec *executionContext) _Value(ctx context.Context, sel ast.SelectionSet, obj graph.Value) graphql.Marshaler { + switch obj := (obj).(type) { + case nil: return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case graph.IntValue: + return ec._IntValue(ctx, sel, &obj) + case *graph.IntValue: + if obj == nil { + return graphql.Null } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputFields(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null + return ec._IntValue(ctx, sel, obj) + case graph.DoubleValue: + return ec._DoubleValue(ctx, sel, &obj) + case *graph.DoubleValue: + if obj == nil { + return graphql.Null + } + return ec._DoubleValue(ctx, sel, obj) + case graph.StringValue: + return ec._StringValue(ctx, sel, &obj) + case *graph.StringValue: + if obj == nil { + return graphql.Null + } + return ec._StringValue(ctx, sel, obj) + case graph.BoolValue: + return ec._BoolValue(ctx, sel, &obj) + case *graph.BoolValue: + if obj == nil { + return graphql.Null + } + return ec._BoolValue(ctx, sel, obj) + default: + panic(fmt.Errorf("unexpected type %T", obj)) } - res := resTmp.([]introspection.InputValue) - fc.Result = res - return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___InputValue_name(ctx, field) - case "description": - return ec.fieldContext___InputValue_description(ctx, field) - case "type": - return ec.fieldContext___InputValue_type(ctx, field) - case "defaultValue": - return ec.fieldContext___InputValue_defaultValue(ctx, field) +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var artifactImplementors = []string{"Artifact"} + +func (ec *executionContext) _Artifact(ctx context.Context, sel ast.SelectionSet, obj *graph.Artifact) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, artifactImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Artifact") + case "id": + out.Values[i] = ec._Artifact_id(ctx, field, obj) + case "typeId": + out.Values[i] = ec._Artifact_typeId(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) } - return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) - }, - } - return fc, nil -} + case "uri": + out.Values[i] = ec._Artifact_uri(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "state": + out.Values[i] = ec._Artifact_state(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "name": + out.Values[i] = ec._Artifact_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "externalId": + out.Values[i] = ec._Artifact_externalId(ctx, field, obj) + case "createTimeSinceEpoch": + out.Values[i] = ec._Artifact_createTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "lastUpdateTimeSinceEpoch": + out.Values[i] = ec._Artifact_lastUpdateTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "type": + field := field -func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_ofType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Artifact_type(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "properties": + out.Values[i] = ec._Artifact_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OfType(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null } - if resTmp == nil { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out } -func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) +var artifactPropertyImplementors = []string{"ArtifactProperty"} + +func (ec *executionContext) _ArtifactProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactProperty) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, artifactPropertyImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ArtifactProperty") + case "artifactId": + out.Values[i] = ec._ArtifactProperty_artifactId(ctx, field, obj) + case "name": + out.Values[i] = ec._ArtifactProperty_name(ctx, field, obj) + case "isCustomProperty": + out.Values[i] = ec._ArtifactProperty_isCustomProperty(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null + case "propertyValue": + out.Values[i] = ec._ArtifactProperty_propertyValue(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.SpecifiedByURL(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null } - if resTmp == nil { + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} -func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) } - return fc, nil + + return out } -// endregion **************************** field.gotpl ***************************** +var artifactTypeImplementors = []string{"ArtifactType", "ArtifactTypeInterface", "Type"} -// region **************************** input.gotpl ***************************** +func (ec *executionContext) _ArtifactType(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactType) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, artifactTypeImplementors) -func (ec *executionContext) unmarshalInputInstanceFilter(ctx context.Context, obj interface{}) (graph.InstanceFilter, error) { - var it graph.InstanceFilter - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ArtifactType") + case "id": + out.Values[i] = ec._ArtifactType_id(ctx, field, obj) + case "name": + out.Values[i] = ec._ArtifactType_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "version": + out.Values[i] = ec._ArtifactType_version(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "typeKind": + out.Values[i] = ec._ArtifactType_typeKind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._ArtifactType_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._ArtifactType_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._ArtifactType_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null } - fieldsInOrder := [...]string{"ids", "typeIds", "names", "externalIds"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "ids": - var err error + atomic.AddInt32(&ec.deferred, int32(len(deferred))) - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) - data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Ids = data - case "typeIds": - var err error + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("typeIds")) - data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.TypeIds = data - case "names": - var err error + return out +} - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Names = data - case "externalIds": - var err error +var boolValueImplementors = []string{"BoolValue", "Value"} - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err +func (ec *executionContext) _BoolValue(ctx context.Context, sel ast.SelectionSet, obj *graph.BoolValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, boolValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("BoolValue") + case "value": + out.Values[i] = ec._BoolValue_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - it.ExternalIds = data + default: + panic("unknown field " + strconv.Quote(field.Name)) } } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } - return it, nil -} + atomic.AddInt32(&ec.deferred, int32(len(deferred))) -func (ec *executionContext) unmarshalInputTypeFilter(ctx context.Context, obj interface{}) (graph.TypeFilter, error) { - var it graph.TypeFilter - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) } - fieldsInOrder := [...]string{"ids", "names", "versions", "externalIds"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "ids": - var err error + return out +} - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) - data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Ids = data - case "names": - var err error +var contextImplementors = []string{"Context"} - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Names = data - case "versions": - var err error +func (ec *executionContext) _Context(ctx context.Context, sel ast.SelectionSet, obj *graph.Context) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, contextImplementors) - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("versions")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Context") + case "id": + out.Values[i] = ec._Context_id(ctx, field, obj) + case "typeId": + out.Values[i] = ec._Context_typeId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - it.Versions = data - case "externalIds": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err + case "name": + out.Values[i] = ec._Context_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._Context_externalId(ctx, field, obj) + case "createTimeSinceEpoch": + out.Values[i] = ec._Context_createTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - it.ExternalIds = data + case "lastUpdateTimeSinceEpoch": + out.Values[i] = ec._Context_lastUpdateTimeSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "type": + out.Values[i] = ec._Context_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "parent": + out.Values[i] = ec._Context_parent(ctx, field, obj) + case "children": + out.Values[i] = ec._Context_children(ctx, field, obj) + case "attributions": + out.Values[i] = ec._Context_attributions(ctx, field, obj) + case "associations": + out.Values[i] = ec._Context_associations(ctx, field, obj) + case "properties": + out.Values[i] = ec._Context_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) } } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } - return it, nil + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out } -// endregion **************************** input.gotpl ***************************** +var contextPropertyImplementors = []string{"ContextProperty"} -// region ************************** interface.gotpl *************************** +func (ec *executionContext) _ContextProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextProperty) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, contextPropertyImplementors) -func (ec *executionContext) _Type(ctx context.Context, sel ast.SelectionSet, obj graph.Type) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case graph.ArtifactType: - return ec._ArtifactType(ctx, sel, &obj) - case *graph.ArtifactType: - if obj == nil { - return graphql.Null - } - return ec._ArtifactType(ctx, sel, obj) - case graph.ContextType: - return ec._ContextType(ctx, sel, &obj) - case *graph.ContextType: - if obj == nil { - return graphql.Null - } - return ec._ContextType(ctx, sel, obj) - case graph.ExecutionType: - return ec._ExecutionType(ctx, sel, &obj) - case *graph.ExecutionType: - if obj == nil { - return graphql.Null + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("ContextProperty") + case "contextId": + out.Values[i] = ec._ContextProperty_contextId(ctx, field, obj) + case "name": + out.Values[i] = ec._ContextProperty_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isCustomProperty": + out.Values[i] = ec._ContextProperty_isCustomProperty(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "propertyValue": + out.Values[i] = ec._ContextProperty_propertyValue(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) } - return ec._ExecutionType(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) } -} - -func (ec *executionContext) _Value(ctx context.Context, sel ast.SelectionSet, obj graph.Value) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: + out.Dispatch(ctx) + if out.Invalids > 0 { return graphql.Null - case graph.IntValue: - return ec._IntValue(ctx, sel, &obj) - case *graph.IntValue: - if obj == nil { - return graphql.Null - } - return ec._IntValue(ctx, sel, obj) - case graph.DoubleValue: - return ec._DoubleValue(ctx, sel, &obj) - case *graph.DoubleValue: - if obj == nil { - return graphql.Null - } - return ec._DoubleValue(ctx, sel, obj) - case graph.StringValue: - return ec._StringValue(ctx, sel, &obj) - case *graph.StringValue: - if obj == nil { - return graphql.Null - } - return ec._StringValue(ctx, sel, obj) - case graph.BoolValue: - return ec._BoolValue(ctx, sel, &obj) - case *graph.BoolValue: - if obj == nil { - return graphql.Null - } - return ec._BoolValue(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) } -} -// endregion ************************** interface.gotpl *************************** + atomic.AddInt32(&ec.deferred, int32(len(deferred))) -// region **************************** object.gotpl **************************** + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } -var artifactImplementors = []string{"Artifact"} + return out +} -func (ec *executionContext) _Artifact(ctx context.Context, sel ast.SelectionSet, obj *graph.Artifact) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, artifactImplementors) +var contextTypeImplementors = []string{"ContextType", "ContextTypeInterface", "Type"} + +func (ec *executionContext) _ContextType(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextType) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, contextTypeImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("Artifact") + out.Values[i] = graphql.MarshalString("ContextType") case "id": - out.Values[i] = ec._Artifact_id(ctx, field, obj) - case "typeId": - out.Values[i] = ec._Artifact_typeId(ctx, field, obj) + out.Values[i] = ec._ContextType_id(ctx, field, obj) + case "name": + out.Values[i] = ec._ContextType_name(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + out.Invalids++ } - case "uri": - out.Values[i] = ec._Artifact_uri(ctx, field, obj) + case "version": + out.Values[i] = ec._ContextType_version(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + out.Invalids++ } - case "state": - out.Values[i] = ec._Artifact_state(ctx, field, obj) + case "typeKind": + out.Values[i] = ec._ContextType_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + out.Invalids++ } - case "name": - out.Values[i] = ec._Artifact_name(ctx, field, obj) + case "description": + out.Values[i] = ec._ContextType_description(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + out.Invalids++ } case "externalId": - out.Values[i] = ec._Artifact_externalId(ctx, field, obj) - case "createTimeSinceEpoch": - out.Values[i] = ec._Artifact_createTimeSinceEpoch(ctx, field, obj) + out.Values[i] = ec._ContextType_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._ContextType_properties(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var doubleValueImplementors = []string{"DoubleValue", "Value"} + +func (ec *executionContext) _DoubleValue(ctx context.Context, sel ast.SelectionSet, obj *graph.DoubleValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, doubleValueImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DoubleValue") + case "value": + out.Values[i] = ec._DoubleValue_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var eventImplementors = []string{"Event"} + +func (ec *executionContext) _Event(ctx context.Context, sel ast.SelectionSet, obj *graph.Event) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, eventImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Event") + case "id": + out.Values[i] = ec._Event_id(ctx, field, obj) + case "artifactId": + out.Values[i] = ec._Event_artifactId(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + out.Invalids++ } - case "lastUpdateTimeSinceEpoch": - out.Values[i] = ec._Artifact_lastUpdateTimeSinceEpoch(ctx, field, obj) + case "executionId": + out.Values[i] = ec._Event_executionId(ctx, field, obj) if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + out.Invalids++ } case "type": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Artifact_type(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res + out.Values[i] = ec._Event_type(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) - - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue + case "artifact": + out.Values[i] = ec._Event_artifact(ctx, field, obj) + case "execution": + out.Values[i] = ec._Event_execution(ctx, field, obj) + case "millisecondsSinceEpoch": + out.Values[i] = ec._Event_millisecondsSinceEpoch(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "properties": - out.Values[i] = ec._Artifact_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -7909,28 +12603,34 @@ func (ec *executionContext) _Artifact(ctx context.Context, sel ast.SelectionSet, return out } -var artifactPropertyImplementors = []string{"ArtifactProperty"} +var eventPathImplementors = []string{"EventPath"} -func (ec *executionContext) _ArtifactProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactProperty) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, artifactPropertyImplementors) +func (ec *executionContext) _EventPath(ctx context.Context, sel ast.SelectionSet, obj *graph.EventPath) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, eventPathImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("ArtifactProperty") - case "artifactId": - out.Values[i] = ec._ArtifactProperty_artifactId(ctx, field, obj) - case "name": - out.Values[i] = ec._ArtifactProperty_name(ctx, field, obj) - case "isCustomProperty": - out.Values[i] = ec._ArtifactProperty_isCustomProperty(ctx, field, obj) + out.Values[i] = graphql.MarshalString("EventPath") + case "eventId": + out.Values[i] = ec._EventPath_eventId(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "propertyValue": - out.Values[i] = ec._ArtifactProperty_propertyValue(ctx, field, obj) + case "isIndexStep": + out.Values[i] = ec._EventPath_isIndexStep(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "stepIndex": + out.Values[i] = ec._EventPath_stepIndex(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "stepKey": + out.Values[i] = ec._EventPath_stepKey(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -7957,43 +12657,53 @@ func (ec *executionContext) _ArtifactProperty(ctx context.Context, sel ast.Selec return out } -var artifactTypeImplementors = []string{"ArtifactType", "Type"} +var executionImplementors = []string{"Execution"} -func (ec *executionContext) _ArtifactType(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactType) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, artifactTypeImplementors) +func (ec *executionContext) _Execution(ctx context.Context, sel ast.SelectionSet, obj *graph.Execution) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, executionImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("ArtifactType") + out.Values[i] = graphql.MarshalString("Execution") case "id": - out.Values[i] = ec._ArtifactType_id(ctx, field, obj) + out.Values[i] = ec._Execution_id(ctx, field, obj) + case "typeId": + out.Values[i] = ec._Execution_typeId(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "lastKnownState": + out.Values[i] = ec._Execution_lastKnownState(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "name": - out.Values[i] = ec._ArtifactType_name(ctx, field, obj) + out.Values[i] = ec._Execution_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "version": - out.Values[i] = ec._ArtifactType_version(ctx, field, obj) + case "externalId": + out.Values[i] = ec._Execution_externalId(ctx, field, obj) + case "createTimeSinceEpoch": + out.Values[i] = ec._Execution_createTimeSinceEpoch(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "typeKind": - out.Values[i] = ec._ArtifactType_typeKind(ctx, field, obj) + case "lastUpdateTimeSinceEpoch": + out.Values[i] = ec._Execution_lastUpdateTimeSinceEpoch(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "description": - out.Values[i] = ec._ArtifactType_description(ctx, field, obj) + case "type": + out.Values[i] = ec._Execution_type(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "externalId": - out.Values[i] = ec._ArtifactType_externalId(ctx, field, obj) case "properties": - out.Values[i] = ec._ArtifactType_properties(ctx, field, obj) + out.Values[i] = ec._Execution_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8017,19 +12727,31 @@ func (ec *executionContext) _ArtifactType(ctx context.Context, sel ast.Selection return out } -var boolValueImplementors = []string{"BoolValue", "Value"} +var executionPropertyImplementors = []string{"ExecutionProperty"} -func (ec *executionContext) _BoolValue(ctx context.Context, sel ast.SelectionSet, obj *graph.BoolValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, boolValueImplementors) +func (ec *executionContext) _ExecutionProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionProperty) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, executionPropertyImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("BoolValue") - case "value": - out.Values[i] = ec._BoolValue_value(ctx, field, obj) + out.Values[i] = graphql.MarshalString("ExecutionProperty") + case "executionId": + out.Values[i] = ec._ExecutionProperty_executionId(ctx, field, obj) + case "name": + out.Values[i] = ec._ExecutionProperty_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "isCustomProperty": + out.Values[i] = ec._ExecutionProperty_isCustomProperty(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "propertyValue": + out.Values[i] = ec._ExecutionProperty_propertyValue(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -8056,56 +12778,53 @@ func (ec *executionContext) _BoolValue(ctx context.Context, sel ast.SelectionSet return out } -var contextImplementors = []string{"Context"} +var executionTypeImplementors = []string{"ExecutionType", "ExecutionTypeInterface", "Type"} -func (ec *executionContext) _Context(ctx context.Context, sel ast.SelectionSet, obj *graph.Context) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, contextImplementors) +func (ec *executionContext) _ExecutionType(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionType) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, executionTypeImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("Context") + out.Values[i] = graphql.MarshalString("ExecutionType") case "id": - out.Values[i] = ec._Context_id(ctx, field, obj) - case "typeId": - out.Values[i] = ec._Context_typeId(ctx, field, obj) + out.Values[i] = ec._ExecutionType_id(ctx, field, obj) + case "name": + out.Values[i] = ec._ExecutionType_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "name": - out.Values[i] = ec._Context_name(ctx, field, obj) + case "version": + out.Values[i] = ec._ExecutionType_version(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "externalId": - out.Values[i] = ec._Context_externalId(ctx, field, obj) - case "createTimeSinceEpoch": - out.Values[i] = ec._Context_createTimeSinceEpoch(ctx, field, obj) + case "typeKind": + out.Values[i] = ec._ExecutionType_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "lastUpdateTimeSinceEpoch": - out.Values[i] = ec._Context_lastUpdateTimeSinceEpoch(ctx, field, obj) + case "description": + out.Values[i] = ec._ExecutionType_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "type": - out.Values[i] = ec._Context_type(ctx, field, obj) + case "externalId": + out.Values[i] = ec._ExecutionType_externalId(ctx, field, obj) + case "inputType": + out.Values[i] = ec._ExecutionType_inputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "outputType": + out.Values[i] = ec._ExecutionType_outputType(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "parent": - out.Values[i] = ec._Context_parent(ctx, field, obj) - case "children": - out.Values[i] = ec._Context_children(ctx, field, obj) - case "attributions": - out.Values[i] = ec._Context_attributions(ctx, field, obj) - case "associations": - out.Values[i] = ec._Context_associations(ctx, field, obj) case "properties": - out.Values[i] = ec._Context_properties(ctx, field, obj) + out.Values[i] = ec._ExecutionType_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8129,34 +12848,82 @@ func (ec *executionContext) _Context(ctx context.Context, sel ast.SelectionSet, return out } -var contextPropertyImplementors = []string{"ContextProperty"} +var intValueImplementors = []string{"IntValue", "Value"} -func (ec *executionContext) _ContextProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextProperty) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, contextPropertyImplementors) +func (ec *executionContext) _IntValue(ctx context.Context, sel ast.SelectionSet, obj *graph.IntValue) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, intValueImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("ContextProperty") - case "contextId": - out.Values[i] = ec._ContextProperty_contextId(ctx, field, obj) + out.Values[i] = graphql.MarshalString("IntValue") + case "value": + out.Values[i] = ec._IntValue_value(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.deferred, int32(len(deferred))) + + for label, dfs := range deferred { + ec.processDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var mlmdDatasetImplementors = []string{"MlmdDataset", "ArtifactTypeInterface", "Type"} + +func (ec *executionContext) _MlmdDataset(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdDataset) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdDatasetImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("MlmdDataset") + case "id": + out.Values[i] = ec._MlmdDataset_id(ctx, field, obj) case "name": - out.Values[i] = ec._ContextProperty_name(ctx, field, obj) + out.Values[i] = ec._MlmdDataset_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "isCustomProperty": - out.Values[i] = ec._ContextProperty_isCustomProperty(ctx, field, obj) + case "version": + out.Values[i] = ec._MlmdDataset_version(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "typeKind": + out.Values[i] = ec._MlmdDataset_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "propertyValue": - out.Values[i] = ec._ContextProperty_propertyValue(ctx, field, obj) + case "description": + out.Values[i] = ec._MlmdDataset_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "externalId": + out.Values[i] = ec._MlmdDataset_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._MlmdDataset_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8180,43 +12947,53 @@ func (ec *executionContext) _ContextProperty(ctx context.Context, sel ast.Select return out } -var contextTypeImplementors = []string{"ContextType", "Type"} +var mlmdDeployImplementors = []string{"MlmdDeploy", "ExecutionTypeInterface", "Type"} -func (ec *executionContext) _ContextType(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextType) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, contextTypeImplementors) +func (ec *executionContext) _MlmdDeploy(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdDeploy) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdDeployImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("ContextType") + out.Values[i] = graphql.MarshalString("MlmdDeploy") case "id": - out.Values[i] = ec._ContextType_id(ctx, field, obj) + out.Values[i] = ec._MlmdDeploy_id(ctx, field, obj) case "name": - out.Values[i] = ec._ContextType_name(ctx, field, obj) + out.Values[i] = ec._MlmdDeploy_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "version": - out.Values[i] = ec._ContextType_version(ctx, field, obj) + out.Values[i] = ec._MlmdDeploy_version(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "typeKind": - out.Values[i] = ec._ContextType_typeKind(ctx, field, obj) + out.Values[i] = ec._MlmdDeploy_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "description": - out.Values[i] = ec._ContextType_description(ctx, field, obj) + out.Values[i] = ec._MlmdDeploy_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "externalId": - out.Values[i] = ec._ContextType_externalId(ctx, field, obj) + out.Values[i] = ec._MlmdDeploy_externalId(ctx, field, obj) + case "inputType": + out.Values[i] = ec._MlmdDeploy_inputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "outputType": + out.Values[i] = ec._MlmdDeploy_outputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "properties": - out.Values[i] = ec._ContextType_properties(ctx, field, obj) + out.Values[i] = ec._MlmdDeploy_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8240,22 +13017,53 @@ func (ec *executionContext) _ContextType(ctx context.Context, sel ast.SelectionS return out } -var doubleValueImplementors = []string{"DoubleValue", "Value"} +var mlmdEvaluateImplementors = []string{"MlmdEvaluate", "ExecutionTypeInterface", "Type"} -func (ec *executionContext) _DoubleValue(ctx context.Context, sel ast.SelectionSet, obj *graph.DoubleValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, doubleValueImplementors) +func (ec *executionContext) _MlmdEvaluate(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdEvaluate) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdEvaluateImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("DoubleValue") - case "value": - out.Values[i] = ec._DoubleValue_value(ctx, field, obj) + out.Values[i] = graphql.MarshalString("MlmdEvaluate") + case "id": + out.Values[i] = ec._MlmdEvaluate_id(ctx, field, obj) + case "name": + out.Values[i] = ec._MlmdEvaluate_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "version": + out.Values[i] = ec._MlmdEvaluate_version(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "typeKind": + out.Values[i] = ec._MlmdEvaluate_typeKind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._MlmdEvaluate_description(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "externalId": + out.Values[i] = ec._MlmdEvaluate_externalId(ctx, field, obj) + case "inputType": + out.Values[i] = ec._MlmdEvaluate_inputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "outputType": + out.Values[i] = ec._MlmdEvaluate_outputType(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "properties": + out.Values[i] = ec._MlmdEvaluate_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8279,43 +13087,43 @@ func (ec *executionContext) _DoubleValue(ctx context.Context, sel ast.SelectionS return out } -var eventImplementors = []string{"Event"} +var mlmdMetricsImplementors = []string{"MlmdMetrics", "ArtifactTypeInterface", "Type"} -func (ec *executionContext) _Event(ctx context.Context, sel ast.SelectionSet, obj *graph.Event) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, eventImplementors) +func (ec *executionContext) _MlmdMetrics(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdMetrics) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdMetricsImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("Event") + out.Values[i] = graphql.MarshalString("MlmdMetrics") case "id": - out.Values[i] = ec._Event_id(ctx, field, obj) - case "artifactId": - out.Values[i] = ec._Event_artifactId(ctx, field, obj) + out.Values[i] = ec._MlmdMetrics_id(ctx, field, obj) + case "name": + out.Values[i] = ec._MlmdMetrics_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "executionId": - out.Values[i] = ec._Event_executionId(ctx, field, obj) + case "version": + out.Values[i] = ec._MlmdMetrics_version(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "type": - out.Values[i] = ec._Event_type(ctx, field, obj) + case "typeKind": + out.Values[i] = ec._MlmdMetrics_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "artifact": - out.Values[i] = ec._Event_artifact(ctx, field, obj) - case "execution": - out.Values[i] = ec._Event_execution(ctx, field, obj) - case "millisecondsSinceEpoch": - out.Values[i] = ec._Event_millisecondsSinceEpoch(ctx, field, obj) + case "description": + out.Values[i] = ec._MlmdMetrics_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "externalId": + out.Values[i] = ec._MlmdMetrics_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._MlmdMetrics_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8339,37 +13147,43 @@ func (ec *executionContext) _Event(ctx context.Context, sel ast.SelectionSet, ob return out } -var eventPathImplementors = []string{"EventPath"} +var mlmdModelImplementors = []string{"MlmdModel", "ArtifactTypeInterface", "Type"} -func (ec *executionContext) _EventPath(ctx context.Context, sel ast.SelectionSet, obj *graph.EventPath) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, eventPathImplementors) +func (ec *executionContext) _MlmdModel(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdModel) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdModelImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("EventPath") - case "eventId": - out.Values[i] = ec._EventPath_eventId(ctx, field, obj) + out.Values[i] = graphql.MarshalString("MlmdModel") + case "id": + out.Values[i] = ec._MlmdModel_id(ctx, field, obj) + case "name": + out.Values[i] = ec._MlmdModel_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "isIndexStep": - out.Values[i] = ec._EventPath_isIndexStep(ctx, field, obj) + case "version": + out.Values[i] = ec._MlmdModel_version(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "stepIndex": - out.Values[i] = ec._EventPath_stepIndex(ctx, field, obj) + case "typeKind": + out.Values[i] = ec._MlmdModel_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "stepKey": - out.Values[i] = ec._EventPath_stepKey(ctx, field, obj) + case "description": + out.Values[i] = ec._MlmdModel_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "externalId": + out.Values[i] = ec._MlmdModel_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._MlmdModel_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8393,53 +13207,53 @@ func (ec *executionContext) _EventPath(ctx context.Context, sel ast.SelectionSet return out } -var executionImplementors = []string{"Execution"} +var mlmdProcessImplementors = []string{"MlmdProcess", "ExecutionTypeInterface", "Type"} -func (ec *executionContext) _Execution(ctx context.Context, sel ast.SelectionSet, obj *graph.Execution) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, executionImplementors) +func (ec *executionContext) _MlmdProcess(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdProcess) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdProcessImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("Execution") + out.Values[i] = graphql.MarshalString("MlmdProcess") case "id": - out.Values[i] = ec._Execution_id(ctx, field, obj) - case "typeId": - out.Values[i] = ec._Execution_typeId(ctx, field, obj) + out.Values[i] = ec._MlmdProcess_id(ctx, field, obj) + case "name": + out.Values[i] = ec._MlmdProcess_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "lastKnownState": - out.Values[i] = ec._Execution_lastKnownState(ctx, field, obj) + case "version": + out.Values[i] = ec._MlmdProcess_version(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "name": - out.Values[i] = ec._Execution_name(ctx, field, obj) + case "typeKind": + out.Values[i] = ec._MlmdProcess_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "externalId": - out.Values[i] = ec._Execution_externalId(ctx, field, obj) - case "createTimeSinceEpoch": - out.Values[i] = ec._Execution_createTimeSinceEpoch(ctx, field, obj) + case "description": + out.Values[i] = ec._MlmdProcess_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "lastUpdateTimeSinceEpoch": - out.Values[i] = ec._Execution_lastUpdateTimeSinceEpoch(ctx, field, obj) + case "externalId": + out.Values[i] = ec._MlmdProcess_externalId(ctx, field, obj) + case "inputType": + out.Values[i] = ec._MlmdProcess_inputType(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "type": - out.Values[i] = ec._Execution_type(ctx, field, obj) + case "outputType": + out.Values[i] = ec._MlmdProcess_outputType(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "properties": - out.Values[i] = ec._Execution_properties(ctx, field, obj) + out.Values[i] = ec._MlmdProcess_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8463,34 +13277,43 @@ func (ec *executionContext) _Execution(ctx context.Context, sel ast.SelectionSet return out } -var executionPropertyImplementors = []string{"ExecutionProperty"} +var mlmdStatisticsImplementors = []string{"MlmdStatistics", "ArtifactTypeInterface", "Type"} -func (ec *executionContext) _ExecutionProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionProperty) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, executionPropertyImplementors) +func (ec *executionContext) _MlmdStatistics(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdStatistics) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdStatisticsImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("ExecutionProperty") - case "executionId": - out.Values[i] = ec._ExecutionProperty_executionId(ctx, field, obj) + out.Values[i] = graphql.MarshalString("MlmdStatistics") + case "id": + out.Values[i] = ec._MlmdStatistics_id(ctx, field, obj) case "name": - out.Values[i] = ec._ExecutionProperty_name(ctx, field, obj) + out.Values[i] = ec._MlmdStatistics_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "isCustomProperty": - out.Values[i] = ec._ExecutionProperty_isCustomProperty(ctx, field, obj) + case "version": + out.Values[i] = ec._MlmdStatistics_version(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "propertyValue": - out.Values[i] = ec._ExecutionProperty_propertyValue(ctx, field, obj) + case "typeKind": + out.Values[i] = ec._MlmdStatistics_typeKind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._MlmdStatistics_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "externalId": + out.Values[i] = ec._MlmdStatistics_externalId(ctx, field, obj) + case "properties": + out.Values[i] = ec._MlmdStatistics_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8514,53 +13337,53 @@ func (ec *executionContext) _ExecutionProperty(ctx context.Context, sel ast.Sele return out } -var executionTypeImplementors = []string{"ExecutionType", "Type"} +var mlmdTrainImplementors = []string{"MlmdTrain", "ExecutionTypeInterface", "Type"} -func (ec *executionContext) _ExecutionType(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionType) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, executionTypeImplementors) +func (ec *executionContext) _MlmdTrain(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdTrain) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdTrainImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("ExecutionType") + out.Values[i] = graphql.MarshalString("MlmdTrain") case "id": - out.Values[i] = ec._ExecutionType_id(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_id(ctx, field, obj) case "name": - out.Values[i] = ec._ExecutionType_name(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_name(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "version": - out.Values[i] = ec._ExecutionType_version(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_version(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "typeKind": - out.Values[i] = ec._ExecutionType_typeKind(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_typeKind(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "description": - out.Values[i] = ec._ExecutionType_description(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "externalId": - out.Values[i] = ec._ExecutionType_externalId(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_externalId(ctx, field, obj) case "inputType": - out.Values[i] = ec._ExecutionType_inputType(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_inputType(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "outputType": - out.Values[i] = ec._ExecutionType_outputType(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_outputType(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "properties": - out.Values[i] = ec._ExecutionType_properties(ctx, field, obj) + out.Values[i] = ec._MlmdTrain_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8584,22 +13407,53 @@ func (ec *executionContext) _ExecutionType(ctx context.Context, sel ast.Selectio return out } -var intValueImplementors = []string{"IntValue", "Value"} +var mlmdTransformImplementors = []string{"MlmdTransform", "ExecutionTypeInterface", "Type"} -func (ec *executionContext) _IntValue(ctx context.Context, sel ast.SelectionSet, obj *graph.IntValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, intValueImplementors) +func (ec *executionContext) _MlmdTransform(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdTransform) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, mlmdTransformImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("IntValue") - case "value": - out.Values[i] = ec._IntValue_value(ctx, field, obj) + out.Values[i] = graphql.MarshalString("MlmdTransform") + case "id": + out.Values[i] = ec._MlmdTransform_id(ctx, field, obj) + case "name": + out.Values[i] = ec._MlmdTransform_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "version": + out.Values[i] = ec._MlmdTransform_version(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "typeKind": + out.Values[i] = ec._MlmdTransform_typeKind(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "description": + out.Values[i] = ec._MlmdTransform_description(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "externalId": + out.Values[i] = ec._MlmdTransform_externalId(ctx, field, obj) + case "inputType": + out.Values[i] = ec._MlmdTransform_inputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "outputType": + out.Values[i] = ec._MlmdTransform_outputType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "properties": + out.Values[i] = ec._MlmdTransform_properties(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -8793,6 +13647,25 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "mlmdDataset": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_mlmdDataset(ctx, field) + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "__type": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { @@ -9403,6 +14276,16 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return res } +func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._MlmdDataset(ctx, sel, v) +} + func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) { res, err := graphql.UnmarshalString(v) return res, graphql.ErrorOnPath(ctx, err) @@ -10321,6 +15204,53 @@ func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsb return &res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { + if v == nil { + return graphql.Null + } + ret := make(graphql.Array, len(v)) + var wg sync.WaitGroup + isLen1 := len(v) == 1 + if !isLen1 { + wg.Add(len(v)) + } + for i := range v { + i := i + fc := &graphql.FieldContext{ + Index: &i, + Result: &v[i], + } + ctx := graphql.WithFieldContext(ctx, fc) + f := func(i int) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = nil + } + }() + if !isLen1 { + defer wg.Done() + } + ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) + } + if isLen1 { + f(i) + } else { + go f(i) + } + + } + wg.Wait() + + for _, e := range ret { + if e == graphql.Null { + return graphql.Null + } + } + + return ret +} + func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { if v == nil { return nil, nil diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index 2955bfb8..6373a356 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -11,12 +11,6 @@ import ( "github.com/dhirajsb/ml-metadata-go-server/model/graph" ) -// Type is the resolver for the type field. -func (r *artifactResolver) Type(ctx context.Context, obj *graph.Artifact) (*graph.ArtifactType, error) { - id := "1" - return &graph.ArtifactType{ID: &id, Name: "TestType"}, nil -} - // Types is the resolver for the types field. func (r *queryResolver) Types(ctx context.Context, filter *graph.TypeFilter) ([]graph.Type, error) { //panic(fmt.Errorf("not implemented: Types - types")) @@ -60,11 +54,12 @@ func (r *queryResolver) Events(ctx context.Context) ([]*graph.Event, error) { panic(fmt.Errorf("not implemented: Events - events")) } -// Artifact returns ArtifactResolver implementation. -func (r *Resolver) Artifact() ArtifactResolver { return &artifactResolver{r} } +// MlmdDataset is the resolver for the mlmdDataset field. +func (r *queryResolver) MlmdDataset(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.MlmdDataset, error) { + panic(fmt.Errorf("not implemented: MlmdDataset - mlmdDataset")) +} // Query returns QueryResolver implementation. func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } -type artifactResolver struct{ *Resolver } type queryResolver struct{ *Resolver } From 960bb987aa79d0e4ee284104efcd219b06f47c60 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Sat, 9 Sep 2023 17:44:46 -0700 Subject: [PATCH 026/254] Updated db model from ml-metadata mysql schema, includes indices --- cmd/migrate.go | 2 +- model/db/artifact.gen.go | 16 ++--- model/db/artifactproperty.gen.go | 16 ++--- model/db/association.gen.go | 6 +- model/db/attribution.gen.go | 6 +- model/db/context.gen.go | 12 ++-- model/db/contextproperty.gen.go | 18 ++--- model/db/event.gen.go | 10 +-- model/db/eventpath.gen.go | 8 +-- model/db/execution.gen.go | 14 ++-- model/db/executionproperty.gen.go | 18 ++--- model/db/mlmdenv.gen.go | 2 +- model/db/parentcontext.gen.go | 2 +- model/db/parenttype.gen.go | 18 +++++ model/db/type.gen.go | 16 ++--- model/db/typeproperty.gen.go | 4 +- server/grpc_server.go | 115 +++++++++++++++++------------- 17 files changed, 158 insertions(+), 125 deletions(-) create mode 100644 model/db/parenttype.gen.go diff --git a/cmd/migrate.go b/cmd/migrate.go index 5c7dfcaf..1894fb72 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -156,7 +156,7 @@ func loadLibraries(dbConn *gorm.DB) error { if err != nil { return fmt.Errorf("failed to add library from file %s: %w", path, err) } - glog.Infof("added %d artifacts, %d contexts and %d execution types from library file %s", + glog.Infof("created/updated %d artifacts, %d contexts and %d execution types from library file %s", len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) return nil }) diff --git a/model/db/artifact.gen.go b/model/db/artifact.gen.go index ed3e41ab..022a01e7 100644 --- a/model/db/artifact.gen.go +++ b/model/db/artifact.gen.go @@ -8,14 +8,14 @@ const TableNameArtifact = "Artifact" // Artifact mapped from table type Artifact struct { - ID int64 `gorm:"column:id;primaryKey" json:"-"` - TypeID int64 `gorm:"column:type_id;not null" json:"-"` - URI string `gorm:"column:uri;not null" json:"-"` - State int32 `gorm:"column:state;not null" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` - ExternalID string `gorm:"column:external_id;not null" json:"-"` - CreateTimeSinceEpoch int32 `gorm:"column:create_time_since_epoch;not null" json:"-"` - LastUpdateTimeSinceEpoch int32 `gorm:"column:last_update_time_since_epoch;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueArtifactTypeName,priority:1" json:"-"` + URI *string `gorm:"column:uri;index:idx_artifact_uri,priority:1" json:"-"` + State *int64 `gorm:"column:state" json:"-"` + Name *string `gorm:"column:name;uniqueIndex:UniqueArtifactTypeName,priority:2" json:"-"` + ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_artifact_external_id,priority:1" json:"-"` + CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_artifact_create_time_since_epoch,priority:1" json:"-"` + LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_artifact_last_update_time_since_epoch,priority:1" json:"-"` } // TableName Artifact's table name diff --git a/model/db/artifactproperty.gen.go b/model/db/artifactproperty.gen.go index 8986042e..cb615844 100644 --- a/model/db/artifactproperty.gen.go +++ b/model/db/artifactproperty.gen.go @@ -8,14 +8,14 @@ const TableNameArtifactProperty = "ArtifactProperty" // ArtifactProperty mapped from table type ArtifactProperty struct { - ArtifactID int64 `gorm:"column:artifact_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey" json:"-"` - IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` - IntValue *int32 `gorm:"column:int_value" json:"-"` - DoubleValue *float64 `gorm:"column:double_value" json:"-"` - StringValue *string `gorm:"column:string_value" json:"-"` - ByteValue []byte `gorm:"column:byte_value" json:"-"` - ProtoValue []byte `gorm:"column:proto_value" json:"-"` + ArtifactID int64 `gorm:"column:artifact_id;primaryKey" json:"-"` + Name string `gorm:"column:name;primaryKey;index:idx_artifact_property_double,priority:1;index:idx_artifact_property_string,priority:1;index:idx_artifact_property_int,priority:1" json:"-"` + IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_artifact_property_double,priority:2;index:idx_artifact_property_string,priority:2;index:idx_artifact_property_int,priority:2" json:"-"` + IntValue *int64 `gorm:"column:int_value;index:idx_artifact_property_int,priority:3" json:"-"` + DoubleValue *float64 `gorm:"column:double_value;index:idx_artifact_property_double,priority:3" json:"-"` + StringValue *string `gorm:"column:string_value;index:idx_artifact_property_string,priority:3" json:"-"` + ByteValue *[]byte `gorm:"column:byte_value" json:"-"` + ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` BoolValue *bool `gorm:"column:bool_value" json:"-"` } diff --git a/model/db/association.gen.go b/model/db/association.gen.go index d46f2cf3..b977dd99 100644 --- a/model/db/association.gen.go +++ b/model/db/association.gen.go @@ -8,9 +8,9 @@ const TableNameAssociation = "Association" // Association mapped from table type Association struct { - ID int64 `gorm:"column:id;primaryKey" json:"-"` - ContextID int64 `gorm:"column:context_id;not null" json:"-"` - ExecutionID int64 `gorm:"column:execution_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + ContextID int64 `gorm:"column:context_id;not null;uniqueIndex:UniqueAssociation,priority:1" json:"-"` + ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueAssociation,priority:2" json:"-"` } // TableName Association's table name diff --git a/model/db/attribution.gen.go b/model/db/attribution.gen.go index 4d12133c..e5a71526 100644 --- a/model/db/attribution.gen.go +++ b/model/db/attribution.gen.go @@ -8,9 +8,9 @@ const TableNameAttribution = "Attribution" // Attribution mapped from table type Attribution struct { - ID int64 `gorm:"column:id;primaryKey" json:"-"` - ContextID int64 `gorm:"column:context_id;not null" json:"-"` - ArtifactID int64 `gorm:"column:artifact_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + ContextID int64 `gorm:"column:context_id;not null;uniqueIndex:UniqueAttribution,priority:1" json:"-"` + ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueAttribution,priority:2" json:"-"` } // TableName Attribution's table name diff --git a/model/db/context.gen.go b/model/db/context.gen.go index 1f90622f..0d681fb2 100644 --- a/model/db/context.gen.go +++ b/model/db/context.gen.go @@ -8,12 +8,12 @@ const TableNameContext = "Context" // Context mapped from table type Context struct { - ID int64 `gorm:"column:id;primaryKey" json:"-"` - TypeID int64 `gorm:"column:type_id;not null" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` - ExternalID string `gorm:"column:external_id;not null" json:"-"` - CreateTimeSinceEpoch int32 `gorm:"column:create_time_since_epoch;not null" json:"-"` - LastUpdateTimeSinceEpoch int32 `gorm:"column:last_update_time_since_epoch;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueContextName,priority:1" json:"-"` + Name string `gorm:"column:name;not null;uniqueIndex:UniqueContextName,priority:2" json:"-"` + ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_context_external_id,priority:1" json:"-"` + CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_context_create_time_since_epoch,priority:1" json:"-"` + LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_context_last_update_time_since_epoch,priority:1" json:"-"` } // TableName Context's table name diff --git a/model/db/contextproperty.gen.go b/model/db/contextproperty.gen.go index 1dc87c18..64cb841f 100644 --- a/model/db/contextproperty.gen.go +++ b/model/db/contextproperty.gen.go @@ -8,15 +8,15 @@ const TableNameContextProperty = "ContextProperty" // ContextProperty mapped from table type ContextProperty struct { - ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` - IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` - IntValue int32 `gorm:"column:int_value;not null" json:"-"` - DoubleValue float64 `gorm:"column:double_value;not null" json:"-"` - StringValue string `gorm:"column:string_value;not null" json:"-"` - ByteValue []byte `gorm:"column:byte_value;not null" json:"-"` - ProtoValue []byte `gorm:"column:proto_value;not null" json:"-"` - BoolValue bool `gorm:"column:bool_value;not null" json:"-"` + ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` + Name string `gorm:"column:name;primaryKey;index:idx_context_property_int,priority:1;index:idx_context_property_string,priority:1;index:idx_context_property_double,priority:1" json:"-"` + IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_context_property_int,priority:2;index:idx_context_property_string,priority:2;index:idx_context_property_double,priority:2" json:"-"` + IntValue *int64 `gorm:"column:int_value;index:idx_context_property_int,priority:3" json:"-"` + DoubleValue *float64 `gorm:"column:double_value;index:idx_context_property_double,priority:3" json:"-"` + StringValue *string `gorm:"column:string_value;index:idx_context_property_string,priority:3" json:"-"` + ByteValue *[]byte `gorm:"column:byte_value" json:"-"` + ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` + BoolValue *bool `gorm:"column:bool_value" json:"-"` } // TableName ContextProperty's table name diff --git a/model/db/event.gen.go b/model/db/event.gen.go index cd878f05..125c4e2b 100644 --- a/model/db/event.gen.go +++ b/model/db/event.gen.go @@ -8,11 +8,11 @@ const TableNameEvent = "Event" // Event mapped from table type Event struct { - ID int64 `gorm:"column:id;primaryKey" json:"-"` - ArtifactID int64 `gorm:"column:artifact_id;not null" json:"-"` - ExecutionID int64 `gorm:"column:execution_id;not null" json:"-"` - Type int32 `gorm:"column:type;not null" json:"-"` - MillisecondsSinceEpoch int32 `gorm:"column:milliseconds_since_epoch;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueEvent,priority:1" json:"-"` + ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueEvent,priority:2;index:idx_event_execution_id,priority:1" json:"-"` + Type int64 `gorm:"column:type;not null;uniqueIndex:UniqueEvent,priority:3" json:"-"` + MillisecondsSinceEpoch *int64 `gorm:"column:milliseconds_since_epoch" json:"-"` } // TableName Event's table name diff --git a/model/db/eventpath.gen.go b/model/db/eventpath.gen.go index 7b3830a2..1007865d 100644 --- a/model/db/eventpath.gen.go +++ b/model/db/eventpath.gen.go @@ -8,10 +8,10 @@ const TableNameEventPath = "EventPath" // EventPath mapped from table type EventPath struct { - EventID int64 `gorm:"column:event_id;not null" json:"-"` - IsIndexStep int32 `gorm:"column:is_index_step;not null" json:"-"` - StepIndex int32 `gorm:"column:step_index;not null" json:"-"` - StepKey string `gorm:"column:step_key;not null" json:"-"` + EventID int64 `gorm:"column:event_id;not null;index:idx_eventpath_event_id,priority:1" json:"-"` + IsIndexStep bool `gorm:"column:is_index_step;not null" json:"-"` + StepIndex *int64 `gorm:"column:step_index" json:"-"` + StepKey *string `gorm:"column:step_key" json:"-"` } // TableName EventPath's table name diff --git a/model/db/execution.gen.go b/model/db/execution.gen.go index 15aaee8f..eaa418b5 100644 --- a/model/db/execution.gen.go +++ b/model/db/execution.gen.go @@ -8,13 +8,13 @@ const TableNameExecution = "Execution" // Execution mapped from table type Execution struct { - ID int64 `gorm:"column:id;primaryKey" json:"-"` - TypeID int64 `gorm:"column:type_id;not null" json:"-"` - LastKnownState int32 `gorm:"column:last_known_state;not null" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` - ExternalID string `gorm:"column:external_id;not null" json:"-"` - CreateTimeSinceEpoch int32 `gorm:"column:create_time_since_epoch;not null" json:"-"` - LastUpdateTimeSinceEpoch int32 `gorm:"column:last_update_time_since_epoch;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueExecutionTypeName,priority:1" json:"-"` + LastKnownState *int64 `gorm:"column:last_known_state" json:"-"` + Name *string `gorm:"column:name;uniqueIndex:UniqueExecutionTypeName,priority:2" json:"-"` + ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_execution_external_id,priority:1" json:"-"` + CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_execution_create_time_since_epoch,priority:1" json:"-"` + LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_execution_last_update_time_since_epoch,priority:1" json:"-"` } // TableName Execution's table name diff --git a/model/db/executionproperty.gen.go b/model/db/executionproperty.gen.go index 27208a3b..59735488 100644 --- a/model/db/executionproperty.gen.go +++ b/model/db/executionproperty.gen.go @@ -8,15 +8,15 @@ const TableNameExecutionProperty = "ExecutionProperty" // ExecutionProperty mapped from table type ExecutionProperty struct { - ExecutionID int64 `gorm:"column:execution_id;primaryKey" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` - IsCustomProperty int32 `gorm:"column:is_custom_property;not null" json:"-"` - IntValue int32 `gorm:"column:int_value;not null" json:"-"` - DoubleValue float64 `gorm:"column:double_value;not null" json:"-"` - StringValue string `gorm:"column:string_value;not null" json:"-"` - ByteValue []byte `gorm:"column:byte_value;not null" json:"-"` - ProtoValue []byte `gorm:"column:proto_value;not null" json:"-"` - BoolValue bool `gorm:"column:bool_value;not null" json:"-"` + ExecutionID int64 `gorm:"column:execution_id;primaryKey" json:"-"` + Name string `gorm:"column:name;primaryKey;index:idx_execution_property_string,priority:1;index:idx_execution_property_int,priority:1;index:idx_execution_property_double,priority:1" json:"-"` + IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_execution_property_string,priority:2;index:idx_execution_property_int,priority:2;index:idx_execution_property_double,priority:2" json:"-"` + IntValue *int64 `gorm:"column:int_value;index:idx_execution_property_int,priority:3" json:"-"` + DoubleValue *float64 `gorm:"column:double_value;index:idx_execution_property_double,priority:3" json:"-"` + StringValue *string `gorm:"column:string_value;index:idx_execution_property_string,priority:3" json:"-"` + ByteValue *[]byte `gorm:"column:byte_value" json:"-"` + ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` + BoolValue *bool `gorm:"column:bool_value" json:"-"` } // TableName ExecutionProperty's table name diff --git a/model/db/mlmdenv.gen.go b/model/db/mlmdenv.gen.go index 8941d513..c12c60d1 100644 --- a/model/db/mlmdenv.gen.go +++ b/model/db/mlmdenv.gen.go @@ -8,7 +8,7 @@ const TableNameMLMDEnv = "MLMDEnv" // MLMDEnv mapped from table type MLMDEnv struct { - SchemaVersion int32 `gorm:"column:schema_version;primaryKey" json:"-"` + SchemaVersion int64 `gorm:"column:schema_version;primaryKey" json:"-"` } // TableName MLMDEnv's table name diff --git a/model/db/parentcontext.gen.go b/model/db/parentcontext.gen.go index f8664e19..8e9b2e9f 100644 --- a/model/db/parentcontext.gen.go +++ b/model/db/parentcontext.gen.go @@ -9,7 +9,7 @@ const TableNameParentContext = "ParentContext" // ParentContext mapped from table type ParentContext struct { ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` - ParentContextID int64 `gorm:"column:parent_context_id;not null" json:"-"` + ParentContextID int64 `gorm:"column:parent_context_id;primaryKey;index:idx_parentcontext_parent_context_id,priority:1" json:"-"` } // TableName ParentContext's table name diff --git a/model/db/parenttype.gen.go b/model/db/parenttype.gen.go new file mode 100644 index 00000000..f4863b9d --- /dev/null +++ b/model/db/parenttype.gen.go @@ -0,0 +1,18 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package db + +const TableNameParentType = "ParentType" + +// ParentType mapped from table +type ParentType struct { + TypeID int64 `gorm:"column:type_id;primaryKey" json:"-"` + ParentTypeID int64 `gorm:"column:parent_type_id;primaryKey" json:"-"` +} + +// TableName ParentType's table name +func (*ParentType) TableName() string { + return TableNameParentType +} diff --git a/model/db/type.gen.go b/model/db/type.gen.go index 48dc8a4d..00e9fbed 100644 --- a/model/db/type.gen.go +++ b/model/db/type.gen.go @@ -8,14 +8,14 @@ const TableNameType = "Type" // Type mapped from table type Type struct { - ID int64 `gorm:"column:id;primaryKey" json:"-"` - Name string `gorm:"column:name;not null" json:"-"` - Version string `gorm:"column:version;not null" json:"-"` - TypeKind int32 `gorm:"column:type_kind;not null" json:"-"` - Description string `gorm:"column:description;not null" json:"-"` - InputType string `gorm:"column:input_type;not null" json:"-"` - OutputType string `gorm:"column:output_type;not null" json:"-"` - ExternalID string `gorm:"column:external_id;not null" json:"-"` + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + Name string `gorm:"column:name;not null;uniqueIndex:idx_type_name,priority:1" json:"-"` + Version *string `gorm:"column:version" json:"-"` + TypeKind int32 `gorm:"column:type_kind;not null" json:"-"` + Description *string `gorm:"column:description" json:"-"` + InputType *string `gorm:"column:input_type" json:"-"` + OutputType *string `gorm:"column:output_type" json:"-"` + ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_type_external_id,priority:1" json:"-"` } // TableName Type's table name diff --git a/model/db/typeproperty.gen.go b/model/db/typeproperty.gen.go index 663f6451..c60ebbea 100644 --- a/model/db/typeproperty.gen.go +++ b/model/db/typeproperty.gen.go @@ -9,8 +9,8 @@ const TableNameTypeProperty = "TypeProperty" // TypeProperty mapped from table type TypeProperty struct { TypeID int64 `gorm:"column:type_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey;not null" json:"-"` - DataType *int32 `gorm:"column:data_type" json:"-"` + Name string `gorm:"column:name;primaryKey" json:"-"` + DataType int32 `gorm:"column:data_type;not null" json:"-"` } // TableName TypeProperty's table name diff --git a/server/grpc_server.go b/server/grpc_server.go index cb1625de..6d9e5269 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -46,27 +46,23 @@ func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { var REQUIRED_TYPE_FIELDS = []string{"name"} func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) + ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) artifactType := request.GetArtifactType() + properties := request.ArtifactType.Properties err = requiredFields(REQUIRED_TYPE_FIELDS, artifactType.Name) if err != nil { return nil, err } value := &db.Type{ - Name: *artifactType.Name, - TypeKind: int32(ARTIFACT_TYPE), - } - nilSafeCopy(&value.Version, artifactType.Version, identity[string]) - nilSafeCopy(&value.Description, artifactType.Description, identity[string]) - nilSafeCopy(&value.ExternalID, artifactType.ExternalId, identity[string]) - - if err = dbConn.Create(value).Error; err != nil { - err = fmt.Errorf("error creating artifact type %s: %v", value.Name, err) - return nil, err + Name: *artifactType.Name, + Version: artifactType.Version, + TypeKind: int32(ARTIFACT_TYPE), + Description: artifactType.Description, + ExternalID: artifactType.ExternalId, } - err = g.createTypeProperties(ctx, request.ArtifactType.Properties, value) + err = g.createOrUpdateType(ctx, value, properties) if err != nil { return nil, err } @@ -76,8 +72,24 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif }, nil } +func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, + properties map[string]proto.PropertyType) error { + // TODO handle CanAdd, CanOmit properties from type request + dbConn, _ := FromContext(ctx) + + if err := dbConn.Where("name = ?", value.Name).Assign(value).FirstOrCreate(value).Error; err != nil { + err = fmt.Errorf("error creating type %s: %v", value.Name, err) + return err + } + err := g.createTypeProperties(ctx, properties, value.ID) + if err != nil { + return err + } + return nil +} + func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) + ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) executionType := request.GetExecutionType() @@ -86,17 +98,13 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec return nil, err } value := &db.Type{ - Name: *executionType.Name, - TypeKind: int32(EXECUTION_TYPE), - } - nilSafeCopy(&value.Version, executionType.Version, identity[string]) - nilSafeCopy(&value.Description, executionType.Description, identity[string]) - nilSafeCopy(&value.ExternalID, executionType.ExternalId, identity[string]) - if err = dbConn.Create(value).Error; err != nil { - err = fmt.Errorf("error creating execution type %s: %v", value.Name, err) - return nil, err + Name: *executionType.Name, + Version: executionType.Version, + TypeKind: int32(EXECUTION_TYPE), + Description: executionType.Description, + ExternalID: executionType.ExternalId, } - err = g.createTypeProperties(ctx, request.ExecutionType.Properties, value) + err = g.createOrUpdateType(ctx, value, executionType.Properties) if err != nil { return nil, err } @@ -107,7 +115,7 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec } func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) + ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) contextType := request.GetContextType() @@ -116,17 +124,16 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex return nil, err } value := &db.Type{ - Name: *contextType.Name, - TypeKind: int32(CONTEXT_TYPE), + Name: *contextType.Name, + Version: contextType.Version, + TypeKind: int32(CONTEXT_TYPE), + Description: contextType.Description, + ExternalID: contextType.ExternalId, } - nilSafeCopy(&value.Version, contextType.Version, identity[string]) - nilSafeCopy(&value.Description, contextType.Description, identity[string]) - nilSafeCopy(&value.ExternalID, contextType.ExternalId, identity[string]) - if err = dbConn.Create(value).Error; err != nil { - err = fmt.Errorf("error creating context type %s: %v", value.Name, err) + err = g.createOrUpdateType(ctx, value, contextType.Properties) + if err != nil { return nil, err } - err = g.createTypeProperties(ctx, request.ContextType.Properties, value) if err != nil { return nil, err } @@ -203,13 +210,13 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifact return nil, err } value := &db.Artifact{ - TypeID: *artifact.TypeId, - URI: *artifact.Uri, + TypeID: *artifact.TypeId, + URI: artifact.Uri, + Name: artifact.Name, + ExternalID: artifact.ExternalId, } nilSafeCopy(&value.ID, artifact.Id, identity[int64]) - nilSafeCopy(&value.State, artifact.State, artifactStateToInt32) - nilSafeCopy(&value.Name, artifact.Name, identity[string]) - nilSafeCopy(&value.ExternalID, artifact.ExternalId, identity[string]) + nilSafeCopy(&value.State, artifact.State, artifactStateToInt64) // create in DB if err = dbConn.Create(value).Error; err != nil { err = fmt.Errorf("error creating artifact with type_id[%d], name[%s]: %w", value.TypeID, value.Name, err) @@ -472,19 +479,20 @@ func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { panic("implement me") } -func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, value *db.Type) (err error) { +func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, typeId int64) (err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { number := int32(prop.Number()) property := &db.TypeProperty{ - TypeID: value.ID, + TypeID: typeId, Name: propName, - DataType: &number, + DataType: number, } - if err = dbConn.Create(property).Error; err != nil { - err = fmt.Errorf("error creating type property for type_id[%d] with name[%s]: %v", value.ID, propName, err) + if err = dbConn.Where("type_id = ? AND name = ?", typeId, propName). + Assign(property).FirstOrCreate(property).Error; err != nil { + err = fmt.Errorf("error creating type property for type_id[%d] with name[%s]: %v", typeId, propName, err) return err } } @@ -501,13 +509,12 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int Name: propName, } if isCustomProperty { - property.IsCustomProperty = 1 + property.IsCustomProperty = true } // TODO handle polymorphic value with null columns intValue, ok := prop.GetValue().(*proto.Value_IntValue) if ok { - i := int32(intValue.IntValue) - property.IntValue = &i + property.IntValue = &intValue.IntValue } doubleValue, ok := prop.GetValue().(*proto.Value_DoubleValue) if ok { @@ -519,11 +526,16 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int } structValue, ok := prop.GetValue().(*proto.Value_StructValue) if ok { - property.ByteValue = []byte(fmt.Sprintf("%s", structValue.StructValue)) + json, err2 := structValue.StructValue.MarshalJSON() + if err2 != nil { + err = fmt.Errorf("error marshaling struct %s value: %w", propName, err2) + return err + } + property.ByteValue = &json } protoValue, ok := prop.GetValue().(*proto.Value_ProtoValue) if ok { - property.ProtoValue = []byte(fmt.Sprintf("%s", protoValue.ProtoValue)) + property.ProtoValue = &protoValue.ProtoValue.Value } boolValue, ok := prop.GetValue().(*proto.Value_BoolValue) if ok { @@ -537,8 +549,11 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int return nil } -func identity[T int64 | string](i T) T { return i } -func artifactStateToInt32(i proto.Artifact_State) int32 { return int32(i) } +func identity[T int64 | string](i T) T { return i } +func artifactStateToInt64(i proto.Artifact_State) *int64 { + var result = int64(i) + return &result +} func requiredFields(names []string, args ...interface{}) error { var missing []string @@ -553,7 +568,7 @@ func requiredFields(names []string, args ...interface{}) error { return nil } -func nilSafeCopy[D int32 | int64 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { +func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { if src != nil { *dest = f(*src) } From e29bda6be3b159e7fa318e9bf05ff323cb7c6c9d Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Sat, 9 Sep 2023 20:35:22 -0700 Subject: [PATCH 027/254] Added DB model relationships --- model/db/artifact.gen.go | 6 ++++++ model/db/association.gen.go | 2 ++ model/db/attribution.gen.go | 2 ++ model/db/context.gen.go | 10 ++++++++++ model/db/event.gen.go | 6 +++++- model/db/execution.gen.go | 6 ++++++ model/db/type.gen.go | 5 ++++- 7 files changed, 35 insertions(+), 2 deletions(-) diff --git a/model/db/artifact.gen.go b/model/db/artifact.gen.go index 022a01e7..7545c277 100644 --- a/model/db/artifact.gen.go +++ b/model/db/artifact.gen.go @@ -16,6 +16,12 @@ type Artifact struct { ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_artifact_external_id,priority:1" json:"-"` CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_artifact_create_time_since_epoch,priority:1" json:"-"` LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_artifact_last_update_time_since_epoch,priority:1" json:"-"` + + // relationships + Properties []ArtifactProperty + ArtifactType Type `gorm:"foreignKey:TypeID;references:ID"` + Attributions []Attribution `gorm:"foreignKey:ArtifactID;references:ID"` + Events []Event } // TableName Artifact's table name diff --git a/model/db/association.gen.go b/model/db/association.gen.go index b977dd99..cb108c82 100644 --- a/model/db/association.gen.go +++ b/model/db/association.gen.go @@ -11,6 +11,8 @@ type Association struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` ContextID int64 `gorm:"column:context_id;not null;uniqueIndex:UniqueAssociation,priority:1" json:"-"` ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueAssociation,priority:2" json:"-"` + Context Context + Execution Execution } // TableName Association's table name diff --git a/model/db/attribution.gen.go b/model/db/attribution.gen.go index e5a71526..f169e201 100644 --- a/model/db/attribution.gen.go +++ b/model/db/attribution.gen.go @@ -11,6 +11,8 @@ type Attribution struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` ContextID int64 `gorm:"column:context_id;not null;uniqueIndex:UniqueAttribution,priority:1" json:"-"` ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueAttribution,priority:2" json:"-"` + Context Context + Artifact Artifact } // TableName Attribution's table name diff --git a/model/db/context.gen.go b/model/db/context.gen.go index 0d681fb2..ea6c7559 100644 --- a/model/db/context.gen.go +++ b/model/db/context.gen.go @@ -14,6 +14,16 @@ type Context struct { ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_context_external_id,priority:1" json:"-"` CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_context_create_time_since_epoch,priority:1" json:"-"` LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_context_last_update_time_since_epoch,priority:1" json:"-"` + + // relationships + Properties []ContextProperty + ContextType Type `gorm:"foreignKey:TypeID;references:ID"` + Attributions []Attribution `gorm:"foreignKey:ContextID;references:ID"` + Associations []Association `gorm:"foreignKey:ContextID;references:ID"` + + // self-reference for context graphs + Parents []ParentContext `gorm:"foreignKey:ContextID;references:ID"` + Children []ParentContext `gorm:"foreignKey:ParentContextID;references:ID"` } // TableName Context's table name diff --git a/model/db/event.gen.go b/model/db/event.gen.go index 125c4e2b..7c436960 100644 --- a/model/db/event.gen.go +++ b/model/db/event.gen.go @@ -12,7 +12,11 @@ type Event struct { ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueEvent,priority:1" json:"-"` ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueEvent,priority:2;index:idx_event_execution_id,priority:1" json:"-"` Type int64 `gorm:"column:type;not null;uniqueIndex:UniqueEvent,priority:3" json:"-"` - MillisecondsSinceEpoch *int64 `gorm:"column:milliseconds_since_epoch" json:"-"` + MillisecondsSinceEpoch *int64 `gorm:"autoCreateTime:milli;column:milliseconds_since_epoch;not null" json:"-"` + + // relationships + Artifact Artifact + Execution Execution } // TableName Event's table name diff --git a/model/db/execution.gen.go b/model/db/execution.gen.go index eaa418b5..f97fe896 100644 --- a/model/db/execution.gen.go +++ b/model/db/execution.gen.go @@ -15,6 +15,12 @@ type Execution struct { ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_execution_external_id,priority:1" json:"-"` CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_execution_create_time_since_epoch,priority:1" json:"-"` LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_execution_last_update_time_since_epoch,priority:1" json:"-"` + + // relationships + Properties []ExecutionProperty + ExecutionType Type `gorm:"foreignKey:TypeID;references:ID"` + Associations []Association `gorm:"foreignKey:ExecutionID;references:ID"` + Events []Event } // TableName Execution's table name diff --git a/model/db/type.gen.go b/model/db/type.gen.go index 00e9fbed..7b626e28 100644 --- a/model/db/type.gen.go +++ b/model/db/type.gen.go @@ -11,11 +11,14 @@ type Type struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` Name string `gorm:"column:name;not null;uniqueIndex:idx_type_name,priority:1" json:"-"` Version *string `gorm:"column:version" json:"-"` - TypeKind int32 `gorm:"column:type_kind;not null" json:"-"` + TypeKind int32 `gorm:"column:type_kind;not null" json:"-"` Description *string `gorm:"column:description" json:"-"` InputType *string `gorm:"column:input_type" json:"-"` OutputType *string `gorm:"column:output_type" json:"-"` ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_type_external_id,priority:1" json:"-"` + + // relationships + Properties []TypeProperty } // TableName Type's table name From e227e85f302a9700db664806e2716b2b4fa519a5 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 15 Sep 2023 16:13:59 -0700 Subject: [PATCH 028/254] Changed README title --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1d3dba1b..4b08e726 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ml-metadata-go-server +# model-registry A go based server that implements a gRPC interface for [ml_metadata](https://github.com/google/ml-metadata/) library. It adds other features on top of the functionality offered by the gRPC interface. ## Pre-requisites: From b9874dced97458642d801480ccdad8c51aa2d1dc Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 15 Sep 2023 16:40:56 -0700 Subject: [PATCH 029/254] Fixed go project repository references --- .gitignore | 4 +- Makefile | 8 +- README.md | 6 +- .../ml_metadata/proto/metadata_source.proto | 2 +- .../ml_metadata/proto/metadata_store.proto | 2 +- .../proto/metadata_store_service.proto | 2 +- cmd/migrate.go | 10 +- cmd/root.go | 10 +- cmd/serve.go | 6 +- go.mod | 2 +- gqlgen.yml | 2 +- main.go | 4 +- model/library/metadata_library.go | 2 +- server/graph/base-schema.resolvers.go | 2 +- server/graph/generated.go | 188 +++++++++--------- server/graph/schema.resolvers.go | 2 +- server/grpc_server.go | 6 +- 17 files changed, 129 insertions(+), 129 deletions(-) diff --git a/.gitignore b/.gitignore index 4377d252..a2bdd65d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .idea -.ml-metadata-go-server.yaml -ml-metadata-go-server +.model-registry.yaml +model-registry ml_metadata/proto/*.go metadata.sqlite.db vendor diff --git a/Makefile b/Makefile index 18102e82..f9b12a62 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -ml-metadata-go-server: build +model-registry: build ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto protoc -I./api/grpc --go_out=. --go_opt=paths=source_relative \ @@ -19,7 +19,7 @@ vet: .PHONY: clean clean: - rm -Rf ./ml-metadata-go-server ml_metadata/proto/*.go ./model/graph/*.go + rm -Rf ./model-registry ml_metadata/proto/*.go ./model/graph/*.go .PHONY: vendor vendor: @@ -48,6 +48,6 @@ run/client: gen .PHONY: serve serve: build - ./ml-metadata-go-server serve --logtostderr=true + ./model-registry serve --logtostderr=true -all: ml-metadata-go-server +all: model-registry diff --git a/README.md b/README.md index 4b08e726..9e8fa804 100644 --- a/README.md +++ b/README.md @@ -17,18 +17,18 @@ make build ``` The generated binary uses spf13 cmdline args. More information on using the server can be obtained by running the command: ``` -./ml-metadata-go-server --help +./model-registry --help ``` ## Creating/Migrating Server DB The server uses a local SQLite DB file (`metadata.sqlite.db` by default), which can be configured using the `-d` cmdline option. The following command creates the DB: ``` -./ml-metadata-go-server migrate +./model-registry migrate ``` ### Loading metadata library Run the following command to load a metadata library: ``` -./ml-metadata-go-server migrate -m config/metadata-library +./model-registry migrate -m config/metadata-library ``` Note that currently no duplicate detection is done as the implementation is a WIP proof of concept. Running this command multiple times will create duplicate metadata types. diff --git a/api/grpc/ml_metadata/proto/metadata_source.proto b/api/grpc/ml_metadata/proto/metadata_source.proto index 3fc8584c..ee0dbdb6 100644 --- a/api/grpc/ml_metadata/proto/metadata_source.proto +++ b/api/grpc/ml_metadata/proto/metadata_source.proto @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ // The returned results from a MetadataSource. syntax = "proto3"; -option go_package = "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/ml_metadata/proto"; package ml_metadata; diff --git a/api/grpc/ml_metadata/proto/metadata_store.proto b/api/grpc/ml_metadata/proto/metadata_store.proto index c7fddb3d..0abb54f6 100644 --- a/api/grpc/ml_metadata/proto/metadata_store.proto +++ b/api/grpc/ml_metadata/proto/metadata_store.proto @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ syntax = "proto2"; -option go_package = "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/ml_metadata/proto"; package ml_metadata; diff --git a/api/grpc/ml_metadata/proto/metadata_store_service.proto b/api/grpc/ml_metadata/proto/metadata_store_service.proto index d7238cf0..f8266068 100644 --- a/api/grpc/ml_metadata/proto/metadata_store_service.proto +++ b/api/grpc/ml_metadata/proto/metadata_store_service.proto @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ syntax = "proto2"; -option go_package = "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/ml_metadata/proto"; package ml_metadata; diff --git a/cmd/migrate.go b/cmd/migrate.go index 1894fb72..6b7bce49 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -18,11 +18,11 @@ package cmd import ( "context" "fmt" - "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" - "github.com/dhirajsb/ml-metadata-go-server/model/db" - "github.com/dhirajsb/ml-metadata-go-server/model/library" - "github.com/dhirajsb/ml-metadata-go-server/server" "github.com/golang/glog" + "github.com/opendatahub-io/model-registry/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/model/db" + "github.com/opendatahub-io/model-registry/model/library" + "github.com/opendatahub-io/model-registry/server" "github.com/spf13/cobra" yaml "gopkg.in/yaml.v3" "gorm.io/gorm" @@ -37,7 +37,7 @@ var migrateCmd = &cobra.Command{ Use: "migrate", Short: "Migrate ml-metadata DB to latest schema", Long: `This command migrates an existing DB to the latest schema -used by ml-metadata-go-server. It can also create a new DB if it doesn't exist. +used by model-registry. It can also create a new DB if it doesn't exist. This command can create a new ml-metadata Sqlite DB, or migrate an existing DB to the latest schema required by this server.`, diff --git a/cmd/root.go b/cmd/root.go index e429c679..38537913 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -29,9 +29,9 @@ var cfgFile string // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "ml-metadata-go-server", + Use: "model-registry", Short: "A go server for ml-metadata", - Long: `The ml-metadata-go-server is a gRPC server that stores metadata + Long: `The model-registry is a gRPC server that stores metadata for ML applications. It's based on the ml-metadata project that provides a python client library @@ -61,7 +61,7 @@ func init() { // Cobra supports persistent flags, which, if defined here, // will be global for your application. - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.ml-metadata-go-server.yaml)") + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.model-registry.yaml)") // also add standard glog flags rootCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) @@ -81,10 +81,10 @@ func initConfig() { home, err := os.UserHomeDir() cobra.CheckErr(err) - // Search config in home directory with name ".ml-metadata-go-server" (without extension). + // Search config in home directory with name ".model-registry" (without extension). viper.AddConfigPath(home) viper.SetConfigType("yaml") - viper.SetConfigName(".ml-metadata-go-server") + viper.SetConfigName(".model-registry") } viper.AutomaticEnv() // read in environment variables that match diff --git a/cmd/serve.go b/cmd/serve.go index 9102ecc9..5fd193a4 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -20,11 +20,11 @@ import ( "fmt" "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" - "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" - "github.com/dhirajsb/ml-metadata-go-server/server" - "github.com/dhirajsb/ml-metadata-go-server/server/graph" "github.com/golang/glog" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" + "github.com/opendatahub-io/model-registry/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/server" + "github.com/opendatahub-io/model-registry/server/graph" "github.com/soheilhy/cmux" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" diff --git a/go.mod b/go.mod index 14ebc9d8..bdbec28a 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/dhirajsb/ml-metadata-go-server +module github.com/opendatahub-io/model-registry go 1.19 diff --git a/gqlgen.yml b/gqlgen.yml index b8f9430e..95016e06 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -66,7 +66,7 @@ resolver: # gqlgen will search for any type names in the schema in these go packages # if they match it will use them, otherwise it will generate them. autobind: -# - "github.com/dhirajsb/ml-metadata-go-server/graph/model" +# - "github.com/opendatahub-io/model-registry/graph/model" # This section declares type mapping between the GraphQL and go type systems # diff --git a/main.go b/main.go index 65adbebc..75e605ab 100644 --- a/main.go +++ b/main.go @@ -5,7 +5,7 @@ Licensed 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 + 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, @@ -16,8 +16,8 @@ limitations under the License. package main import ( - "github.com/dhirajsb/ml-metadata-go-server/cmd" "github.com/golang/glog" + "github.com/opendatahub-io/model-registry/cmd" ) func main() { diff --git a/model/library/metadata_library.go b/model/library/metadata_library.go index 6e9a5e96..757d8609 100644 --- a/model/library/metadata_library.go +++ b/model/library/metadata_library.go @@ -1,6 +1,6 @@ package library -import "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" +import "github.com/opendatahub-io/model-registry/ml_metadata/proto" //go:generate go-enum -type=PropertyType diff --git a/server/graph/base-schema.resolvers.go b/server/graph/base-schema.resolvers.go index 004fa1c2..6eff0706 100644 --- a/server/graph/base-schema.resolvers.go +++ b/server/graph/base-schema.resolvers.go @@ -7,7 +7,7 @@ package graph import ( "context" - "github.com/dhirajsb/ml-metadata-go-server/model/graph" + "github.com/opendatahub-io/model-registry/model/graph" ) // Type is the resolver for the type field. diff --git a/server/graph/generated.go b/server/graph/generated.go index 16f2ae9a..dba31a39 100644 --- a/server/graph/generated.go +++ b/server/graph/generated.go @@ -13,7 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/introspection" - "github.com/dhirajsb/ml-metadata-go-server/model/graph" + "github.com/opendatahub-io/model-registry/model/graph" gqlparser "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" ) @@ -1933,7 +1933,7 @@ func (ec *executionContext) field_Artifact_type_args(ctx context.Context, rawArg var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -1963,7 +1963,7 @@ func (ec *executionContext) field_Query_artifactTypes_args(ctx context.Context, var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -1978,7 +1978,7 @@ func (ec *executionContext) field_Query_artifacts_args(ctx context.Context, rawA var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -1993,7 +1993,7 @@ func (ec *executionContext) field_Query_contextTypes_args(ctx context.Context, r var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2008,7 +2008,7 @@ func (ec *executionContext) field_Query_contexts_args(ctx context.Context, rawAr var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2023,7 +2023,7 @@ func (ec *executionContext) field_Query_executionTypes_args(ctx context.Context, var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2038,7 +2038,7 @@ func (ec *executionContext) field_Query_executions_args(ctx context.Context, raw var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2053,7 +2053,7 @@ func (ec *executionContext) field_Query_mlmdDataset_args(ctx context.Context, ra var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2068,7 +2068,7 @@ func (ec *executionContext) field_Query_types_args(ctx context.Context, rawArgs var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2489,7 +2489,7 @@ func (ec *executionContext) _Artifact_type(ctx context.Context, field graphql.Co } res := resTmp.(*graph.ArtifactType) fc.Result = res - return ec.marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) + return ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Artifact_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2557,7 +2557,7 @@ func (ec *executionContext) _Artifact_properties(ctx context.Context, field grap } res := resTmp.([]*graph.ArtifactProperty) fc.Result = res - return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Artifact_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2737,7 +2737,7 @@ func (ec *executionContext) _ArtifactProperty_propertyValue(ctx context.Context, } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3036,7 +3036,7 @@ func (ec *executionContext) _ArtifactType_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ArtifactType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3390,7 +3390,7 @@ func (ec *executionContext) _Context_type(ctx context.Context, field graphql.Col } res := resTmp.(*graph.ContextType) fc.Result = res - return ec.marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) + return ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3447,7 +3447,7 @@ func (ec *executionContext) _Context_parent(ctx context.Context, field graphql.C } res := resTmp.(*graph.Context) fc.Result = res - return ec.marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3514,7 +3514,7 @@ func (ec *executionContext) _Context_children(ctx context.Context, field graphql } res := resTmp.([]*graph.Context) fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_children(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3581,7 +3581,7 @@ func (ec *executionContext) _Context_attributions(ctx context.Context, field gra } res := resTmp.([]*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_attributions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3644,7 +3644,7 @@ func (ec *executionContext) _Context_associations(ctx context.Context, field gra } res := resTmp.([]*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_associations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3705,7 +3705,7 @@ func (ec *executionContext) _Context_properties(ctx context.Context, field graph } res := resTmp.([]*graph.ContextProperty) fc.Result = res - return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3888,7 +3888,7 @@ func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4187,7 +4187,7 @@ func (ec *executionContext) _ContextType_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4453,7 +4453,7 @@ func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.C } res := resTmp.(*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Event_artifact(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4516,7 +4516,7 @@ func (ec *executionContext) _Event_execution(ctx context.Context, field graphql. } res := resTmp.(*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) + return ec.marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Event_execution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5102,7 +5102,7 @@ func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.C } res := resTmp.(*graph.ExecutionType) fc.Result = res - return ec.marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) + return ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Execution_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5163,7 +5163,7 @@ func (ec *executionContext) _Execution_properties(ctx context.Context, field gra } res := resTmp.([]*graph.ExecutionProperty) fc.Result = res - return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Execution_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5346,7 +5346,7 @@ func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5733,7 +5733,7 @@ func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6084,7 +6084,7 @@ func (ec *executionContext) _MlmdDataset_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdDataset_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6479,7 +6479,7 @@ func (ec *executionContext) _MlmdDeploy_properties(ctx context.Context, field gr } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdDeploy_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6874,7 +6874,7 @@ func (ec *executionContext) _MlmdEvaluate_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdEvaluate_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7181,7 +7181,7 @@ func (ec *executionContext) _MlmdMetrics_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdMetrics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7488,7 +7488,7 @@ func (ec *executionContext) _MlmdModel_properties(ctx context.Context, field gra } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdModel_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7883,7 +7883,7 @@ func (ec *executionContext) _MlmdProcess_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdProcess_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8190,7 +8190,7 @@ func (ec *executionContext) _MlmdStatistics_properties(ctx context.Context, fiel } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdStatistics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8585,7 +8585,7 @@ func (ec *executionContext) _MlmdTrain_properties(ctx context.Context, field gra } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdTrain_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8980,7 +8980,7 @@ func (ec *executionContext) _MlmdTransform_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdTransform_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9029,7 +9029,7 @@ func (ec *executionContext) _Query_types(ctx context.Context, field graphql.Coll } res := resTmp.([]graph.Type) fc.Result = res - return ec.marshalOType2ᚕgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) + return ec.marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9081,7 +9081,7 @@ func (ec *executionContext) _Query_artifactTypes(ctx context.Context, field grap } res := resTmp.([]*graph.ArtifactType) fc.Result = res - return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) + return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_artifactTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9149,7 +9149,7 @@ func (ec *executionContext) _Query_contextTypes(ctx context.Context, field graph } res := resTmp.([]*graph.ContextType) fc.Result = res - return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) + return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_contextTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9217,7 +9217,7 @@ func (ec *executionContext) _Query_executionTypes(ctx context.Context, field gra } res := resTmp.([]*graph.ExecutionType) fc.Result = res - return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) + return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_executionTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9289,7 +9289,7 @@ func (ec *executionContext) _Query_artifacts(ctx context.Context, field graphql. } res := resTmp.([]*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_artifacts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9363,7 +9363,7 @@ func (ec *executionContext) _Query_contexts(ctx context.Context, field graphql.C } res := resTmp.([]*graph.Context) fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_contexts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9441,7 +9441,7 @@ func (ec *executionContext) _Query_executions(ctx context.Context, field graphql } res := resTmp.([]*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_executions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9513,7 +9513,7 @@ func (ec *executionContext) _Query_events(ctx context.Context, field graphql.Col } res := resTmp.([]*graph.Event) fc.Result = res - return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) + return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9570,7 +9570,7 @@ func (ec *executionContext) _Query_mlmdDataset(ctx context.Context, field graphq } res := resTmp.([]*graph.MlmdDataset) fc.Result = res - return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) + return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_mlmdDataset(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -14112,7 +14112,7 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o // region ***************************** type.gotpl ***************************** -func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14122,7 +14122,7 @@ func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑm return ec._Artifact(ctx, sel, v) } -func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14132,11 +14132,11 @@ func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋdhirajsb return ec._ArtifactProperty(ctx, sel, v) } -func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { return ec._ArtifactType(ctx, sel, &v) } -func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14161,7 +14161,7 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14171,7 +14171,7 @@ func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑme return ec._Context(ctx, sel, v) } -func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { +func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14181,7 +14181,7 @@ func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋdhirajsb return ec._ContextProperty(ctx, sel, v) } -func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { +func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14191,7 +14191,7 @@ func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋml return ec._ContextType(ctx, sel, v) } -func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { +func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14201,7 +14201,7 @@ func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmeta return ec._Event(ctx, sel, v) } -func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14211,7 +14211,7 @@ func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑ return ec._Execution(ctx, sel, v) } -func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { +func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14221,7 +14221,7 @@ func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋdhirajsb return ec._ExecutionProperty(ctx, sel, v) } -func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { +func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14276,7 +14276,7 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return res } -func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { +func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14301,7 +14301,7 @@ func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.S return res } -func (ec *executionContext) marshalNType2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { +func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14311,7 +14311,7 @@ func (ec *executionContext) marshalNType2githubᚗcomᚋdhirajsbᚋmlᚑmetadata return ec._Type(ctx, sel, v) } -func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { +func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14321,7 +14321,7 @@ func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋdhirajsbᚋml return ec._TypeProperty(ctx, sel, v) } -func (ec *executionContext) marshalNValue2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { +func (ec *executionContext) marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14584,7 +14584,7 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a return res } -func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14611,7 +14611,7 @@ func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋml if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14631,14 +14631,14 @@ func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋdhirajsbᚋml return ret } -func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Artifact(ctx, sel, v) } -func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { +func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14665,7 +14665,7 @@ func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhiraj if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14685,7 +14685,7 @@ func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋdhiraj return ret } -func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14712,7 +14712,7 @@ func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋdhirajsb if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14758,7 +14758,7 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return res } -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14785,7 +14785,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋml if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14799,7 +14799,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋml return ret } -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14826,7 +14826,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋml if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14846,14 +14846,14 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋdhirajsbᚋml return ret } -func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Context(ctx, sel, v) } -func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { +func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14880,7 +14880,7 @@ func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajs if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14900,7 +14900,7 @@ func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋdhirajs return ret } -func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { +func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14927,7 +14927,7 @@ func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋdhirajsbᚋ if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) + ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14947,7 +14947,7 @@ func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋdhirajsbᚋ return ret } -func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { +func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14974,7 +14974,7 @@ func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑm if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) + ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14994,7 +14994,7 @@ func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑm return ret } -func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15021,7 +15021,7 @@ func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋml if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) + ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15041,14 +15041,14 @@ func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋdhirajsbᚋml return ret } -func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Execution(ctx, sel, v) } -func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { +func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15075,7 +15075,7 @@ func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhira if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15095,7 +15095,7 @@ func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋdhira return ret } -func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { +func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15122,7 +15122,7 @@ func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋdhirajsb if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) + ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15196,7 +15196,7 @@ func (ec *executionContext) marshalOID2ᚖstring(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { +func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { if v == nil { return nil, nil } @@ -15204,7 +15204,7 @@ func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋdhirajsb return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { +func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15231,7 +15231,7 @@ func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋdhirajsbᚋ if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) + ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15305,7 +15305,7 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as return res } -func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { +func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15332,7 +15332,7 @@ func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋdhirajsbᚋmlᚑmetad if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNType2githubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐType(ctx, sel, v[i]) + ret[i] = ec.marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15352,7 +15352,7 @@ func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋdhirajsbᚋmlᚑmetad return ret } -func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { +func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { if v == nil { return nil, nil } @@ -15360,7 +15360,7 @@ func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋdhirajsbᚋml return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { +func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15387,7 +15387,7 @@ func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋdhirajsb if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋdhirajsbᚋmlᚑmetadataᚑgoᚑserverᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) } if isLen1 { f(i) diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index 6373a356..2e5d20fb 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -8,7 +8,7 @@ import ( "context" "fmt" - "github.com/dhirajsb/ml-metadata-go-server/model/graph" + "github.com/opendatahub-io/model-registry/model/graph" ) // Types is the resolver for the types field. diff --git a/server/grpc_server.go b/server/grpc_server.go index 6d9e5269..80441f42 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -3,8 +3,8 @@ package server import ( "context" "fmt" - "github.com/dhirajsb/ml-metadata-go-server/ml_metadata/proto" - "github.com/dhirajsb/ml-metadata-go-server/model/db" + "github.com/opendatahub-io/model-registry/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/model/db" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" @@ -219,7 +219,7 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifact nilSafeCopy(&value.State, artifact.State, artifactStateToInt64) // create in DB if err = dbConn.Create(value).Error; err != nil { - err = fmt.Errorf("error creating artifact with type_id[%d], name[%s]: %w", value.TypeID, value.Name, err) + err = fmt.Errorf("error creating artifact with type_id[%d], name[%s]: %w", value.TypeID, *value.Name, err) return nil, err } // create properties in DB From 97d4c5fc3d7b81464f72a5a2ece0b445caf892b3 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 15 Sep 2023 17:45:42 -0700 Subject: [PATCH 030/254] Moved packages to pkg directory --- Makefile | 14 +- .../ml_metadata/proto/metadata_source.proto | 2 +- .../ml_metadata/proto/metadata_store.proto | 2 +- .../proto/metadata_store_service.proto | 2 +- cmd/migrate.go | 42 +- cmd/serve.go | 8 +- gqlgen.yml | 8 +- pkg/ml_metadata/proto/metadata_store.pb.go | 6449 ++++++++++ .../proto/metadata_store_service.pb.go | 10227 ++++++++++++++++ .../proto/metadata_store_service_grpc.pb.go | 2553 ++++ {model => pkg/model}/db/artifact.gen.go | 0 .../model}/db/artifactproperty.gen.go | 0 {model => pkg/model}/db/association.gen.go | 0 {model => pkg/model}/db/attribution.gen.go | 0 {model => pkg/model}/db/context.gen.go | 6 +- .../model}/db/contextproperty.gen.go | 0 {model => pkg/model}/db/event.gen.go | 2 +- {model => pkg/model}/db/eventpath.gen.go | 0 {model => pkg/model}/db/execution.gen.go | 4 +- .../model}/db/executionproperty.gen.go | 0 {model => pkg/model}/db/mlmdenv.gen.go | 0 {model => pkg/model}/db/parentcontext.gen.go | 0 {model => pkg/model}/db/parenttype.gen.go | 0 {model => pkg/model}/db/type.gen.go | 0 {model => pkg/model}/db/typeproperty.gen.go | 0 {model => pkg/model}/graph/models_gen.go | 0 .../model}/library/metadata_library.go | 4 +- .../model}/library/propertytype_enum.go | 0 {server => pkg/server}/db_context.go | 0 .../server}/graph/base-schema.resolvers.go | 2 +- {server => pkg/server}/graph/generated.go | 194 +- {server => pkg/server}/graph/resolver.go | 0 .../server}/graph/schema.resolvers.go | 2 +- {server => pkg/server}/grpc_server.go | 174 +- 34 files changed, 19463 insertions(+), 232 deletions(-) create mode 100644 pkg/ml_metadata/proto/metadata_store.pb.go create mode 100644 pkg/ml_metadata/proto/metadata_store_service.pb.go create mode 100644 pkg/ml_metadata/proto/metadata_store_service_grpc.pb.go rename {model => pkg/model}/db/artifact.gen.go (100%) rename {model => pkg/model}/db/artifactproperty.gen.go (100%) rename {model => pkg/model}/db/association.gen.go (100%) rename {model => pkg/model}/db/attribution.gen.go (100%) rename {model => pkg/model}/db/context.gen.go (85%) rename {model => pkg/model}/db/contextproperty.gen.go (100%) rename {model => pkg/model}/db/event.gen.go (97%) rename {model => pkg/model}/db/eventpath.gen.go (100%) rename {model => pkg/model}/db/execution.gen.go (93%) rename {model => pkg/model}/db/executionproperty.gen.go (100%) rename {model => pkg/model}/db/mlmdenv.gen.go (100%) rename {model => pkg/model}/db/parentcontext.gen.go (100%) rename {model => pkg/model}/db/parenttype.gen.go (100%) rename {model => pkg/model}/db/type.gen.go (100%) rename {model => pkg/model}/db/typeproperty.gen.go (100%) rename {model => pkg/model}/graph/models_gen.go (100%) rename {model => pkg/model}/library/metadata_library.go (95%) rename {model => pkg/model}/library/propertytype_enum.go (100%) rename {server => pkg/server}/db_context.go (100%) rename {server => pkg/server}/graph/base-schema.resolvers.go (92%) rename {server => pkg/server}/graph/generated.go (97%) rename {server => pkg/server}/graph/resolver.go (100%) rename {server => pkg/server}/graph/schema.resolvers.go (97%) rename {server => pkg/server}/grpc_server.go (68%) diff --git a/Makefile b/Makefile index f9b12a62..6afb84d0 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,16 @@ model-registry: build -ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto - protoc -I./api/grpc --go_out=. --go_opt=paths=source_relative \ - --go-grpc_out=. --go-grpc_opt=paths=source_relative $< +pkg/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto + protoc -I./api/grpc --go_out=./pkg --go_opt=paths=source_relative \ + --go-grpc_out=./pkg --go-grpc_opt=paths=source_relative $< .PHONY: gen/grpc -gen/grpc: ml_metadata/proto/metadata_store.pb.go ml_metadata/proto/metadata_store_service.pb.go +gen/grpc: pkg/ml_metadata/proto/metadata_store.pb.go pkg/ml_metadata/proto/metadata_store_service.pb.go .PHONY: gen/graph -gen/graph: model/graph/models_gen.go +gen/graph: pkg/model/graph/models_gen.go -model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml +pkg/model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml go run github.com/99designs/gqlgen generate .PHONY: vet @@ -19,7 +19,7 @@ vet: .PHONY: clean clean: - rm -Rf ./model-registry ml_metadata/proto/*.go ./model/graph/*.go + rm -Rf ./model-registry pkg/ml_metadata/proto/*.go pkg/model/graph/*.go .PHONY: vendor vendor: diff --git a/api/grpc/ml_metadata/proto/metadata_source.proto b/api/grpc/ml_metadata/proto/metadata_source.proto index ee0dbdb6..529ecad5 100644 --- a/api/grpc/ml_metadata/proto/metadata_source.proto +++ b/api/grpc/ml_metadata/proto/metadata_source.proto @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ // The returned results from a MetadataSource. syntax = "proto3"; -option go_package = "github.com/opendatahub-io/model-registry/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto"; package ml_metadata; diff --git a/api/grpc/ml_metadata/proto/metadata_store.proto b/api/grpc/ml_metadata/proto/metadata_store.proto index 0abb54f6..f55ffb20 100644 --- a/api/grpc/ml_metadata/proto/metadata_store.proto +++ b/api/grpc/ml_metadata/proto/metadata_store.proto @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ syntax = "proto2"; -option go_package = "github.com/opendatahub-io/model-registry/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto"; package ml_metadata; diff --git a/api/grpc/ml_metadata/proto/metadata_store_service.proto b/api/grpc/ml_metadata/proto/metadata_store_service.proto index f8266068..485d683c 100644 --- a/api/grpc/ml_metadata/proto/metadata_store_service.proto +++ b/api/grpc/ml_metadata/proto/metadata_store_service.proto @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ syntax = "proto2"; -option go_package = "github.com/opendatahub-io/model-registry/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto"; package ml_metadata; diff --git a/cmd/migrate.go b/cmd/migrate.go index 6b7bce49..9032b3ab 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -19,10 +19,10 @@ import ( "context" "fmt" "github.com/golang/glog" - "github.com/opendatahub-io/model-registry/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/model/db" - "github.com/opendatahub-io/model-registry/model/library" - "github.com/opendatahub-io/model-registry/server" + proto2 "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" + db2 "github.com/opendatahub-io/model-registry/pkg/model/db" + "github.com/opendatahub-io/model-registry/pkg/model/library" + "github.com/opendatahub-io/model-registry/pkg/server" "github.com/spf13/cobra" yaml "gopkg.in/yaml.v3" "gorm.io/gorm" @@ -75,19 +75,19 @@ to the latest schema required by this server.`, func migrateDatabase(dbConn *gorm.DB) error { // TODO add support for more elaborate Gorm migrations err := dbConn.AutoMigrate( - db.Artifact{}, - db.ArtifactProperty{}, - db.Association{}, - db.Attribution{}, - db.Context{}, - db.ContextProperty{}, - db.Event{}, - db.EventPath{}, - db.Execution{}, - db.ExecutionProperty{}, - db.ParentContext{}, - db.Type{}, - db.TypeProperty{}, + db2.Artifact{}, + db2.ArtifactProperty{}, + db2.Association{}, + db2.Attribution{}, + db2.Context{}, + db2.ContextProperty{}, + db2.Event{}, + db2.EventPath{}, + db2.Execution{}, + db2.ExecutionProperty{}, + db2.ParentContext{}, + db2.Type{}, + db2.TypeProperty{}, ) if err != nil { return fmt.Errorf("db migration failed: %w", err) @@ -124,9 +124,9 @@ func loadLibraries(dbConn *gorm.DB) error { return fmt.Errorf("failed to parse library file %s: %w", path, err) } grpcServer := server.NewGrpcServer(dbConn) - typesRequest := proto.PutTypesRequest{} + typesRequest := proto2.PutTypesRequest{} for _, at := range lib.ArtifactTypes { - typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ + typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto2.ArtifactType{ Name: at.Name, Version: at.Version, Description: at.Description, @@ -135,7 +135,7 @@ func loadLibraries(dbConn *gorm.DB) error { }) } for _, ct := range lib.ContextTypes { - typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ + typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto2.ContextType{ Name: ct.Name, Version: ct.Version, Description: ct.Description, @@ -144,7 +144,7 @@ func loadLibraries(dbConn *gorm.DB) error { }) } for _, et := range lib.ExecutionTypes { - typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ + typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto2.ExecutionType{ Name: et.Name, Version: et.Version, Description: et.Description, diff --git a/cmd/serve.go b/cmd/serve.go index 5fd193a4..12eb4230 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -22,9 +22,9 @@ import ( "github.com/99designs/gqlgen/graphql/playground" "github.com/golang/glog" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/opendatahub-io/model-registry/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/server" - "github.com/opendatahub-io/model-registry/server/graph" + "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/pkg/server" + graph2 "github.com/opendatahub-io/model-registry/pkg/server/graph" "github.com/soheilhy/cmux" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" @@ -154,7 +154,7 @@ func runServer(cmd *cobra.Command, args []string) error { func graphQlListenerServer(listener net.Listener, db *gorm.DB) *http.Server { mux := http.NewServeMux() - srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})) + srv := handler.NewDefaultServer(graph2.NewExecutableSchema(graph2.Config{Resolvers: &graph2.Resolver{}})) mux.Handle("/", playground.Handler("GraphQL playground", "/query")) mux.Handle("/query", srv) diff --git a/gqlgen.yml b/gqlgen.yml index 95016e06..d281fe81 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -4,7 +4,7 @@ schema: # Where should the generated server code go? exec: - filename: server/graph/generated.go + filename: pkg/server/graph/generated.go package: graph # Uncomment to enable federation @@ -14,13 +14,13 @@ exec: # Where should any generated models go? model: - filename: model/graph/models_gen.go + filename: pkg/model/graph/models_gen.go package: graph # Where should the resolver implementations go? resolver: layout: follow-schema - dir: server/graph + dir: pkg/server/graph package: graph filename_template: "{name}.resolvers.go" # Optional: turn on to not generate template comments above resolvers @@ -88,4 +88,4 @@ models: Artifact: fields: type: - resolver: true \ No newline at end of file + resolver: true diff --git a/pkg/ml_metadata/proto/metadata_store.pb.go b/pkg/ml_metadata/proto/metadata_store.pb.go new file mode 100644 index 00000000..eab133b4 --- /dev/null +++ b/pkg/ml_metadata/proto/metadata_store.pb.go @@ -0,0 +1,6449 @@ +// Copyright 2019 Google LLC +// +//Licensed 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 +// +//https://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. +//============================================================================== + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v3.20.3 +// source: ml_metadata/proto/metadata_store.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + descriptorpb "google.golang.org/protobuf/types/descriptorpb" + anypb "google.golang.org/protobuf/types/known/anypb" + structpb "google.golang.org/protobuf/types/known/structpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The list of supported property value types. +type PropertyType int32 + +const ( + PropertyType_UNKNOWN PropertyType = 0 + PropertyType_INT PropertyType = 1 + PropertyType_DOUBLE PropertyType = 2 + PropertyType_STRING PropertyType = 3 + // Prefer to use `PROTO` to store structed data since this option has + // inefficient database storage usage. + PropertyType_STRUCT PropertyType = 4 + PropertyType_PROTO PropertyType = 5 + PropertyType_BOOLEAN PropertyType = 6 +) + +// Enum value maps for PropertyType. +var ( + PropertyType_name = map[int32]string{ + 0: "UNKNOWN", + 1: "INT", + 2: "DOUBLE", + 3: "STRING", + 4: "STRUCT", + 5: "PROTO", + 6: "BOOLEAN", + } + PropertyType_value = map[string]int32{ + "UNKNOWN": 0, + "INT": 1, + "DOUBLE": 2, + "STRING": 3, + "STRUCT": 4, + "PROTO": 5, + "BOOLEAN": 6, + } +) + +func (x PropertyType) Enum() *PropertyType { + p := new(PropertyType) + *p = x + return p +} + +func (x PropertyType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PropertyType) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[0].Descriptor() +} + +func (PropertyType) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[0] +} + +func (x PropertyType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *PropertyType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = PropertyType(num) + return nil +} + +// Deprecated: Use PropertyType.Descriptor instead. +func (PropertyType) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{0} +} + +type Artifact_State int32 + +const ( + Artifact_UNKNOWN Artifact_State = 0 + // A state indicating that the artifact may exist. + Artifact_PENDING Artifact_State = 1 + // A state indicating that the artifact should exist, unless something + // external to the system deletes it. + Artifact_LIVE Artifact_State = 2 + // A state indicating that the artifact should be deleted. + Artifact_MARKED_FOR_DELETION Artifact_State = 3 + // A state indicating that the artifact has been deleted. + Artifact_DELETED Artifact_State = 4 + // A state indicating that the artifact has been abandoned, which may be + // due to a failed or cancelled execution. + Artifact_ABANDONED Artifact_State = 5 + // A state indicating that the artifact is a reference artifact. At + // execution start time, the orchestrator produces an output artifact for + // each output key with state PENDING. However, for an intermediate + // artifact, this first artifact's state will be REFERENCE. Intermediate + // artifacts emitted during a component's execution will copy the REFERENCE + // artifact's attributes. At the end of an execution, the artifact state + // should remain REFERENCE instead of being changed to LIVE. + Artifact_REFERENCE Artifact_State = 6 +) + +// Enum value maps for Artifact_State. +var ( + Artifact_State_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PENDING", + 2: "LIVE", + 3: "MARKED_FOR_DELETION", + 4: "DELETED", + 5: "ABANDONED", + 6: "REFERENCE", + } + Artifact_State_value = map[string]int32{ + "UNKNOWN": 0, + "PENDING": 1, + "LIVE": 2, + "MARKED_FOR_DELETION": 3, + "DELETED": 4, + "ABANDONED": 5, + "REFERENCE": 6, + } +) + +func (x Artifact_State) Enum() *Artifact_State { + p := new(Artifact_State) + *p = x + return p +} + +func (x Artifact_State) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Artifact_State) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[1].Descriptor() +} + +func (Artifact_State) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[1] +} + +func (x Artifact_State) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Artifact_State) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Artifact_State(num) + return nil +} + +// Deprecated: Use Artifact_State.Descriptor instead. +func (Artifact_State) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{2, 0} +} + +// An enum of system-defined artifact types. +type ArtifactType_SystemDefinedBaseType int32 + +const ( + ArtifactType_UNSET ArtifactType_SystemDefinedBaseType = 0 + ArtifactType_DATASET ArtifactType_SystemDefinedBaseType = 1 + ArtifactType_MODEL ArtifactType_SystemDefinedBaseType = 2 + ArtifactType_METRICS ArtifactType_SystemDefinedBaseType = 3 + ArtifactType_STATISTICS ArtifactType_SystemDefinedBaseType = 4 +) + +// Enum value maps for ArtifactType_SystemDefinedBaseType. +var ( + ArtifactType_SystemDefinedBaseType_name = map[int32]string{ + 0: "UNSET", + 1: "DATASET", + 2: "MODEL", + 3: "METRICS", + 4: "STATISTICS", + } + ArtifactType_SystemDefinedBaseType_value = map[string]int32{ + "UNSET": 0, + "DATASET": 1, + "MODEL": 2, + "METRICS": 3, + "STATISTICS": 4, + } +) + +func (x ArtifactType_SystemDefinedBaseType) Enum() *ArtifactType_SystemDefinedBaseType { + p := new(ArtifactType_SystemDefinedBaseType) + *p = x + return p +} + +func (x ArtifactType_SystemDefinedBaseType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ArtifactType_SystemDefinedBaseType) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[2].Descriptor() +} + +func (ArtifactType_SystemDefinedBaseType) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[2] +} + +func (x ArtifactType_SystemDefinedBaseType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ArtifactType_SystemDefinedBaseType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ArtifactType_SystemDefinedBaseType(num) + return nil +} + +// Deprecated: Use ArtifactType_SystemDefinedBaseType.Descriptor instead. +func (ArtifactType_SystemDefinedBaseType) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{3, 0} +} + +// Events distinguish between an artifact that is written by the execution +// (possibly as a cache), versus artifacts that are part of the declared +// output of the Execution. For more information on what DECLARED_ means, +// see the comment on the message. +type Event_Type int32 + +const ( + Event_UNKNOWN Event_Type = 0 + Event_DECLARED_OUTPUT Event_Type = 1 // A declared output of the execution. + Event_DECLARED_INPUT Event_Type = 2 // A declared input of the execution. + Event_INPUT Event_Type = 3 // An input of the execution. + Event_OUTPUT Event_Type = 4 // An output of the execution. + Event_INTERNAL_INPUT Event_Type = 5 // An internal input of the execution. + Event_INTERNAL_OUTPUT Event_Type = 6 // An internal output of the execution. + Event_PENDING_OUTPUT Event_Type = 7 // A pending output of the execution. +) + +// Enum value maps for Event_Type. +var ( + Event_Type_name = map[int32]string{ + 0: "UNKNOWN", + 1: "DECLARED_OUTPUT", + 2: "DECLARED_INPUT", + 3: "INPUT", + 4: "OUTPUT", + 5: "INTERNAL_INPUT", + 6: "INTERNAL_OUTPUT", + 7: "PENDING_OUTPUT", + } + Event_Type_value = map[string]int32{ + "UNKNOWN": 0, + "DECLARED_OUTPUT": 1, + "DECLARED_INPUT": 2, + "INPUT": 3, + "OUTPUT": 4, + "INTERNAL_INPUT": 5, + "INTERNAL_OUTPUT": 6, + "PENDING_OUTPUT": 7, + } +) + +func (x Event_Type) Enum() *Event_Type { + p := new(Event_Type) + *p = x + return p +} + +func (x Event_Type) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Event_Type) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[3].Descriptor() +} + +func (Event_Type) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[3] +} + +func (x Event_Type) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Event_Type) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Event_Type(num) + return nil +} + +// Deprecated: Use Event_Type.Descriptor instead. +func (Event_Type) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{4, 0} +} + +// The state of the Execution. The state transitions are +// +// NEW -> RUNNING -> COMPLETE | CACHED | FAILED | CANCELED +// +// CACHED means the execution is skipped due to cached results. +// CANCELED means the execution is skipped due to precondition not met. It is +// different from CACHED in that a CANCELED execution will not have any event +// associated with it. It is different from FAILED in that there is no +// unexpected error happened and it is regarded as a normal state. +type Execution_State int32 + +const ( + Execution_UNKNOWN Execution_State = 0 + Execution_NEW Execution_State = 1 + Execution_RUNNING Execution_State = 2 + Execution_COMPLETE Execution_State = 3 + Execution_FAILED Execution_State = 4 + Execution_CACHED Execution_State = 5 + Execution_CANCELED Execution_State = 6 +) + +// Enum value maps for Execution_State. +var ( + Execution_State_name = map[int32]string{ + 0: "UNKNOWN", + 1: "NEW", + 2: "RUNNING", + 3: "COMPLETE", + 4: "FAILED", + 5: "CACHED", + 6: "CANCELED", + } + Execution_State_value = map[string]int32{ + "UNKNOWN": 0, + "NEW": 1, + "RUNNING": 2, + "COMPLETE": 3, + "FAILED": 4, + "CACHED": 5, + "CANCELED": 6, + } +) + +func (x Execution_State) Enum() *Execution_State { + p := new(Execution_State) + *p = x + return p +} + +func (x Execution_State) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Execution_State) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[4].Descriptor() +} + +func (Execution_State) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[4] +} + +func (x Execution_State) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *Execution_State) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = Execution_State(num) + return nil +} + +// Deprecated: Use Execution_State.Descriptor instead. +func (Execution_State) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{5, 0} +} + +// An enum of system-defined execution types. +type ExecutionType_SystemDefinedBaseType int32 + +const ( + ExecutionType_UNSET ExecutionType_SystemDefinedBaseType = 0 + ExecutionType_TRAIN ExecutionType_SystemDefinedBaseType = 1 + ExecutionType_TRANSFORM ExecutionType_SystemDefinedBaseType = 2 + ExecutionType_PROCESS ExecutionType_SystemDefinedBaseType = 3 + ExecutionType_EVALUATE ExecutionType_SystemDefinedBaseType = 4 + ExecutionType_DEPLOY ExecutionType_SystemDefinedBaseType = 5 +) + +// Enum value maps for ExecutionType_SystemDefinedBaseType. +var ( + ExecutionType_SystemDefinedBaseType_name = map[int32]string{ + 0: "UNSET", + 1: "TRAIN", + 2: "TRANSFORM", + 3: "PROCESS", + 4: "EVALUATE", + 5: "DEPLOY", + } + ExecutionType_SystemDefinedBaseType_value = map[string]int32{ + "UNSET": 0, + "TRAIN": 1, + "TRANSFORM": 2, + "PROCESS": 3, + "EVALUATE": 4, + "DEPLOY": 5, + } +) + +func (x ExecutionType_SystemDefinedBaseType) Enum() *ExecutionType_SystemDefinedBaseType { + p := new(ExecutionType_SystemDefinedBaseType) + *p = x + return p +} + +func (x ExecutionType_SystemDefinedBaseType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ExecutionType_SystemDefinedBaseType) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[5].Descriptor() +} + +func (ExecutionType_SystemDefinedBaseType) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[5] +} + +func (x ExecutionType_SystemDefinedBaseType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ExecutionType_SystemDefinedBaseType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ExecutionType_SystemDefinedBaseType(num) + return nil +} + +// Deprecated: Use ExecutionType_SystemDefinedBaseType.Descriptor instead. +func (ExecutionType_SystemDefinedBaseType) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{6, 0} +} + +// An enum of system-defined context types. +type ContextType_SystemDefinedBaseType int32 + +const ( + ContextType_UNSET ContextType_SystemDefinedBaseType = 0 +) + +// Enum value maps for ContextType_SystemDefinedBaseType. +var ( + ContextType_SystemDefinedBaseType_name = map[int32]string{ + 0: "UNSET", + } + ContextType_SystemDefinedBaseType_value = map[string]int32{ + "UNSET": 0, + } +) + +func (x ContextType_SystemDefinedBaseType) Enum() *ContextType_SystemDefinedBaseType { + p := new(ContextType_SystemDefinedBaseType) + *p = x + return p +} + +func (x ContextType_SystemDefinedBaseType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ContextType_SystemDefinedBaseType) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[6].Descriptor() +} + +func (ContextType_SystemDefinedBaseType) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[6] +} + +func (x ContextType_SystemDefinedBaseType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ContextType_SystemDefinedBaseType) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ContextType_SystemDefinedBaseType(num) + return nil +} + +// Deprecated: Use ContextType_SystemDefinedBaseType.Descriptor instead. +func (ContextType_SystemDefinedBaseType) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{7, 0} +} + +// Connection parameters for SQLite3 based metadata source. +type SqliteMetadataSourceConfig_ConnectionMode int32 + +const ( + SqliteMetadataSourceConfig_UNKNOWN SqliteMetadataSourceConfig_ConnectionMode = 0 + // Connect a metadata source in read-only mode. Connection fail if the + // sqlite3 database at the `filename` does not exist. Any queries modifying + // the database fail. + SqliteMetadataSourceConfig_READONLY SqliteMetadataSourceConfig_ConnectionMode = 1 + // Connect a metadata source in read/write mode. Connection fail if the + // sqlite3 database at the `filename` does not exist. + SqliteMetadataSourceConfig_READWRITE SqliteMetadataSourceConfig_ConnectionMode = 2 + // Similar to READWRITE. In addition, it creates the database if it does not + // exist. + SqliteMetadataSourceConfig_READWRITE_OPENCREATE SqliteMetadataSourceConfig_ConnectionMode = 3 +) + +// Enum value maps for SqliteMetadataSourceConfig_ConnectionMode. +var ( + SqliteMetadataSourceConfig_ConnectionMode_name = map[int32]string{ + 0: "UNKNOWN", + 1: "READONLY", + 2: "READWRITE", + 3: "READWRITE_OPENCREATE", + } + SqliteMetadataSourceConfig_ConnectionMode_value = map[string]int32{ + "UNKNOWN": 0, + "READONLY": 1, + "READWRITE": 2, + "READWRITE_OPENCREATE": 3, + } +) + +func (x SqliteMetadataSourceConfig_ConnectionMode) Enum() *SqliteMetadataSourceConfig_ConnectionMode { + p := new(SqliteMetadataSourceConfig_ConnectionMode) + *p = x + return p +} + +func (x SqliteMetadataSourceConfig_ConnectionMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SqliteMetadataSourceConfig_ConnectionMode) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[7].Descriptor() +} + +func (SqliteMetadataSourceConfig_ConnectionMode) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[7] +} + +func (x SqliteMetadataSourceConfig_ConnectionMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *SqliteMetadataSourceConfig_ConnectionMode) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = SqliteMetadataSourceConfig_ConnectionMode(num) + return nil +} + +// Deprecated: Use SqliteMetadataSourceConfig_ConnectionMode.Descriptor instead. +func (SqliteMetadataSourceConfig_ConnectionMode) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{23, 0} +} + +// Supported fields for Ordering. +type ListOperationOptions_OrderByField_Field int32 + +const ( + ListOperationOptions_OrderByField_FIELD_UNSPECIFIED ListOperationOptions_OrderByField_Field = 0 + ListOperationOptions_OrderByField_CREATE_TIME ListOperationOptions_OrderByField_Field = 1 + ListOperationOptions_OrderByField_LAST_UPDATE_TIME ListOperationOptions_OrderByField_Field = 2 + ListOperationOptions_OrderByField_ID ListOperationOptions_OrderByField_Field = 3 +) + +// Enum value maps for ListOperationOptions_OrderByField_Field. +var ( + ListOperationOptions_OrderByField_Field_name = map[int32]string{ + 0: "FIELD_UNSPECIFIED", + 1: "CREATE_TIME", + 2: "LAST_UPDATE_TIME", + 3: "ID", + } + ListOperationOptions_OrderByField_Field_value = map[string]int32{ + "FIELD_UNSPECIFIED": 0, + "CREATE_TIME": 1, + "LAST_UPDATE_TIME": 2, + "ID": 3, + } +) + +func (x ListOperationOptions_OrderByField_Field) Enum() *ListOperationOptions_OrderByField_Field { + p := new(ListOperationOptions_OrderByField_Field) + *p = x + return p +} + +func (x ListOperationOptions_OrderByField_Field) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (ListOperationOptions_OrderByField_Field) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[8].Descriptor() +} + +func (ListOperationOptions_OrderByField_Field) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[8] +} + +func (x ListOperationOptions_OrderByField_Field) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *ListOperationOptions_OrderByField_Field) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = ListOperationOptions_OrderByField_Field(num) + return nil +} + +// Deprecated: Use ListOperationOptions_OrderByField_Field.Descriptor instead. +func (ListOperationOptions_OrderByField_Field) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{31, 0, 0} +} + +type LineageSubgraphQueryOptions_Direction int32 + +const ( + // Direction is by defult DIRECTION_UNSPECIFIED, which is equivalent to + // BIDIRECTIONAL. + LineageSubgraphQueryOptions_DIRECTION_UNSPECIFIED LineageSubgraphQueryOptions_Direction = 0 + // Indicates tracing the lineage graph by hops in upstream direction. + LineageSubgraphQueryOptions_UPSTREAM LineageSubgraphQueryOptions_Direction = 1 + // Indicates tracing the lineage graph by hops in downstream direction. + LineageSubgraphQueryOptions_DOWNSTREAM LineageSubgraphQueryOptions_Direction = 2 + // Indicates tracing the lineage graph in both directions. + LineageSubgraphQueryOptions_BIDIRECTIONAL LineageSubgraphQueryOptions_Direction = 3 +) + +// Enum value maps for LineageSubgraphQueryOptions_Direction. +var ( + LineageSubgraphQueryOptions_Direction_name = map[int32]string{ + 0: "DIRECTION_UNSPECIFIED", + 1: "UPSTREAM", + 2: "DOWNSTREAM", + 3: "BIDIRECTIONAL", + } + LineageSubgraphQueryOptions_Direction_value = map[string]int32{ + "DIRECTION_UNSPECIFIED": 0, + "UPSTREAM": 1, + "DOWNSTREAM": 2, + "BIDIRECTIONAL": 3, + } +) + +func (x LineageSubgraphQueryOptions_Direction) Enum() *LineageSubgraphQueryOptions_Direction { + p := new(LineageSubgraphQueryOptions_Direction) + *p = x + return p +} + +func (x LineageSubgraphQueryOptions_Direction) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (LineageSubgraphQueryOptions_Direction) Descriptor() protoreflect.EnumDescriptor { + return file_ml_metadata_proto_metadata_store_proto_enumTypes[9].Descriptor() +} + +func (LineageSubgraphQueryOptions_Direction) Type() protoreflect.EnumType { + return &file_ml_metadata_proto_metadata_store_proto_enumTypes[9] +} + +func (x LineageSubgraphQueryOptions_Direction) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Do not use. +func (x *LineageSubgraphQueryOptions_Direction) UnmarshalJSON(b []byte) error { + num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) + if err != nil { + return err + } + *x = LineageSubgraphQueryOptions_Direction(num) + return nil +} + +// Deprecated: Use LineageSubgraphQueryOptions_Direction.Descriptor instead. +func (LineageSubgraphQueryOptions_Direction) EnumDescriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{35, 0} +} + +type SystemTypeExtension struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The name of a system defined type. + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` +} + +func (x *SystemTypeExtension) Reset() { + *x = SystemTypeExtension{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SystemTypeExtension) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SystemTypeExtension) ProtoMessage() {} + +func (x *SystemTypeExtension) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SystemTypeExtension.ProtoReflect.Descriptor instead. +func (*SystemTypeExtension) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{0} +} + +func (x *SystemTypeExtension) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +// A value in properties. +type Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Value: + // + // *Value_IntValue + // *Value_DoubleValue + // *Value_StringValue + // *Value_StructValue + // *Value_ProtoValue + // *Value_BoolValue + Value isValue_Value `protobuf_oneof:"value"` +} + +func (x *Value) Reset() { + *x = Value{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Value) ProtoMessage() {} + +func (x *Value) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Value.ProtoReflect.Descriptor instead. +func (*Value) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{1} +} + +func (m *Value) GetValue() isValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *Value) GetIntValue() int64 { + if x, ok := x.GetValue().(*Value_IntValue); ok { + return x.IntValue + } + return 0 +} + +func (x *Value) GetDoubleValue() float64 { + if x, ok := x.GetValue().(*Value_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +func (x *Value) GetStringValue() string { + if x, ok := x.GetValue().(*Value_StringValue); ok { + return x.StringValue + } + return "" +} + +func (x *Value) GetStructValue() *structpb.Struct { + if x, ok := x.GetValue().(*Value_StructValue); ok { + return x.StructValue + } + return nil +} + +func (x *Value) GetProtoValue() *anypb.Any { + if x, ok := x.GetValue().(*Value_ProtoValue); ok { + return x.ProtoValue + } + return nil +} + +func (x *Value) GetBoolValue() bool { + if x, ok := x.GetValue().(*Value_BoolValue); ok { + return x.BoolValue + } + return false +} + +type isValue_Value interface { + isValue_Value() +} + +type Value_IntValue struct { + IntValue int64 `protobuf:"varint,1,opt,name=int_value,json=intValue,oneof"` +} + +type Value_DoubleValue struct { + DoubleValue float64 `protobuf:"fixed64,2,opt,name=double_value,json=doubleValue,oneof"` +} + +type Value_StringValue struct { + StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,oneof"` +} + +type Value_StructValue struct { + StructValue *structpb.Struct `protobuf:"bytes,4,opt,name=struct_value,json=structValue,oneof"` +} + +type Value_ProtoValue struct { + ProtoValue *anypb.Any `protobuf:"bytes,5,opt,name=proto_value,json=protoValue,oneof"` +} + +type Value_BoolValue struct { + BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,oneof"` +} + +func (*Value_IntValue) isValue_Value() {} + +func (*Value_DoubleValue) isValue_Value() {} + +func (*Value_StringValue) isValue_Value() {} + +func (*Value_StructValue) isValue_Value() {} + +func (*Value_ProtoValue) isValue_Value() {} + +func (*Value_BoolValue) isValue_Value() {} + +type Artifact struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Output only. The unique server generated id of the artifact. + Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + // The client provided name of the artifact. This field is optional. If set, + // it must be unique among all the artifacts of the same artifact type within + // a database instance and cannot be changed once set. + Name *string `protobuf:"bytes,7,opt,name=name" json:"name,omitempty"` + // The id of an ArtifactType. This needs to be specified when an artifact is + // created, and it cannot be changed. + TypeId *int64 `protobuf:"varint,2,opt,name=type_id,json=typeId" json:"type_id,omitempty"` + // Output only. The name of an ArtifactType. + Type *string `protobuf:"bytes,8,opt,name=type" json:"type,omitempty"` + // The uniform resource identifier of the physical artifact. + // May be empty if there is no physical artifact. + Uri *string `protobuf:"bytes,3,opt,name=uri" json:"uri,omitempty"` + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all artifacts within a database instance. + ExternalId *string `protobuf:"bytes,11,opt,name=external_id,json=externalId" json:"external_id,omitempty"` + // Properties of the artifact. + // Properties must be specified in the ArtifactType. + Properties map[string]*Value `protobuf:"bytes,4,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // User provided custom properties which are not defined by its type. + CustomProperties map[string]*Value `protobuf:"bytes,5,rep,name=custom_properties,json=customProperties" json:"custom_properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // The state of the artifact known to the system. + State *Artifact_State `protobuf:"varint,6,opt,name=state,enum=ml_metadata.Artifact_State" json:"state,omitempty"` + // Output only. Create time of the artifact in millisecond since epoch. + CreateTimeSinceEpoch *int64 `protobuf:"varint,9,opt,name=create_time_since_epoch,json=createTimeSinceEpoch" json:"create_time_since_epoch,omitempty"` + // Output only. Last update time of the artifact since epoch in millisecond + // since epoch. + LastUpdateTimeSinceEpoch *int64 `protobuf:"varint,10,opt,name=last_update_time_since_epoch,json=lastUpdateTimeSinceEpoch" json:"last_update_time_since_epoch,omitempty"` + // Output only. + SystemMetadata *anypb.Any `protobuf:"bytes,12,opt,name=system_metadata,json=systemMetadata" json:"system_metadata,omitempty"` +} + +func (x *Artifact) Reset() { + *x = Artifact{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Artifact) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Artifact) ProtoMessage() {} + +func (x *Artifact) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Artifact.ProtoReflect.Descriptor instead. +func (*Artifact) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{2} +} + +func (x *Artifact) GetId() int64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *Artifact) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *Artifact) GetTypeId() int64 { + if x != nil && x.TypeId != nil { + return *x.TypeId + } + return 0 +} + +func (x *Artifact) GetType() string { + if x != nil && x.Type != nil { + return *x.Type + } + return "" +} + +func (x *Artifact) GetUri() string { + if x != nil && x.Uri != nil { + return *x.Uri + } + return "" +} + +func (x *Artifact) GetExternalId() string { + if x != nil && x.ExternalId != nil { + return *x.ExternalId + } + return "" +} + +func (x *Artifact) GetProperties() map[string]*Value { + if x != nil { + return x.Properties + } + return nil +} + +func (x *Artifact) GetCustomProperties() map[string]*Value { + if x != nil { + return x.CustomProperties + } + return nil +} + +func (x *Artifact) GetState() Artifact_State { + if x != nil && x.State != nil { + return *x.State + } + return Artifact_UNKNOWN +} + +func (x *Artifact) GetCreateTimeSinceEpoch() int64 { + if x != nil && x.CreateTimeSinceEpoch != nil { + return *x.CreateTimeSinceEpoch + } + return 0 +} + +func (x *Artifact) GetLastUpdateTimeSinceEpoch() int64 { + if x != nil && x.LastUpdateTimeSinceEpoch != nil { + return *x.LastUpdateTimeSinceEpoch + } + return 0 +} + +func (x *Artifact) GetSystemMetadata() *anypb.Any { + if x != nil { + return x.SystemMetadata + } + return nil +} + +type ArtifactType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The id of the type. 1-1 relationship between type names and IDs. + Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + // The name of the type. It must be unique among ArtifactTypes within a + // database instance. + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // An optional version of the type. An empty string is treated as unset. + Version *string `protobuf:"bytes,4,opt,name=version" json:"version,omitempty"` + // An optional description about the type. + Description *string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"` + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all artifact types within a database + // instance. + ExternalId *string `protobuf:"bytes,7,opt,name=external_id,json=externalId" json:"external_id,omitempty"` + // The schema of the type. + // Properties are always optional in the artifact. + // Properties of an artifact type can be expanded but not contracted (i.e., + // you can add columns but not remove them). + Properties map[string]PropertyType `protobuf:"bytes,3,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=ml_metadata.PropertyType"` + // An optional system defined base_type expressing the intent of the current + // type. This field is useful for the tool builders to utilize the stored MLMD + // information, e.g., `MyModel` ArtifactType could set base_type = MODEL. + BaseType *ArtifactType_SystemDefinedBaseType `protobuf:"varint,6,opt,name=base_type,json=baseType,enum=ml_metadata.ArtifactType_SystemDefinedBaseType" json:"base_type,omitempty"` +} + +func (x *ArtifactType) Reset() { + *x = ArtifactType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArtifactType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArtifactType) ProtoMessage() {} + +func (x *ArtifactType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArtifactType.ProtoReflect.Descriptor instead. +func (*ArtifactType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{3} +} + +func (x *ArtifactType) GetId() int64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *ArtifactType) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *ArtifactType) GetVersion() string { + if x != nil && x.Version != nil { + return *x.Version + } + return "" +} + +func (x *ArtifactType) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *ArtifactType) GetExternalId() string { + if x != nil && x.ExternalId != nil { + return *x.ExternalId + } + return "" +} + +func (x *ArtifactType) GetProperties() map[string]PropertyType { + if x != nil { + return x.Properties + } + return nil +} + +func (x *ArtifactType) GetBaseType() ArtifactType_SystemDefinedBaseType { + if x != nil && x.BaseType != nil { + return *x.BaseType + } + return ArtifactType_UNSET +} + +// An event represents a relationship between an artifact and an execution. +// There are different kinds of events, relating to both input and output, as +// well as how they are used by the mlmd powered system. +// For example, the DECLARED_INPUT and DECLARED_OUTPUT events are part of the +// signature of an execution. For example, consider: +// +// my_result = my_execution({"data":[3,7],"schema":8}) +// +// Where 3, 7, and 8 are artifact_ids, Assuming execution_id of my_execution is +// 12 and artifact_id of my_result is 15, the events are: +// +// { +// artifact_id:3, +// execution_id: 12, +// type:DECLARED_INPUT, +// path:{step:[{"key":"data"},{"index":0}]} +// } +// { +// artifact_id:7, +// execution_id: 12, +// type:DECLARED_INPUT, +// path:{step:[{"key":"data"},{"index":1}]} +// } +// { +// artifact_id:8, +// execution_id: 12, +// type:DECLARED_INPUT, +// path:{step:[{"key":"schema"}]} +// } +// { +// artifact_id:15, +// execution_id: 12, +// type:DECLARED_OUTPUT, +// path:{step:[{"key":"my_result"}]} +// } +// +// Other event types include INPUT/OUTPUT, INTERNAL_INPUT/_OUTPUT and +// PENDING_OUTPUT: +// +// - The INPUT/OUTPUT is an event that actually reads/writes an artifact by an +// execution. The input/output artifacts may not declared in the signature, +// For example, the trainer may output multiple caches of the parameters +// (as an OUTPUT), then finally write the SavedModel as a DECLARED_OUTPUT. +// +// - The INTERNAL_INPUT/_OUTPUT are event types which are only meaningful to +// an orchestration system to keep track of the details for later debugging. +// For example, a fork happened conditioning on an artifact, then an execution +// is triggered, such fork implementing may need to log the read and write +// of artifacts and may not be worth displaying to the users. +// +// For instance, in the above example, +// +// my_result = my_execution({"data":[3,7],"schema":8}) +// +// there is another execution (id: 15), which represents a +// `garbage_collection` step in an orchestration system +// +// gc_result = garbage_collection(my_result) +// +// that cleans `my_result` if needed. The details should be invisible to the +// end users and lineage tracking. The orchestrator can emit following events: +// +// { +// artifact_id: 15, +// execution_id: 15, +// type:INTERNAL_INPUT, +// } +// { +// artifact_id:16, // New artifact containing the GC job result. +// execution_id: 15, +// type:INTERNAL_OUTPUT, +// path:{step:[{"key":"gc_result"}]} +// } +// +// - The PENDING_OUTPUT event is used to indicate that an artifact is +// tentatively associated with an active execution which has not yet been +// finalized. For example, an orchestration system can register output +// artifacts of a running execution with PENDING_OUTPUT events to indicate +// the output artifacts the execution is expected to produce. When the +// execution is finished, the final set of output artifacts can be associated +// with the exeution using OUTPUT events, and any unused artifacts which were +// previously registered with PENDING_OUTPUT events can be updated to set +// their Artifact.State to ABANDONED. +// +// Events are unique of the same +// (artifact_id, execution_id, type) combination within a metadata store. +type Event struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The artifact id is required for an event, and should refer to an + // existing artifact. + ArtifactId *int64 `protobuf:"varint,1,opt,name=artifact_id,json=artifactId" json:"artifact_id,omitempty"` + // The execution_id is required for an event, and should refer to an + // existing execution. + ExecutionId *int64 `protobuf:"varint,2,opt,name=execution_id,json=executionId" json:"execution_id,omitempty"` + // The path in an artifact struct, or the name of an artifact. + Path *Event_Path `protobuf:"bytes,3,opt,name=path" json:"path,omitempty"` + // The type of an event. + Type *Event_Type `protobuf:"varint,4,opt,name=type,enum=ml_metadata.Event_Type" json:"type,omitempty"` + // Time the event occurred + // Epoch is Jan 1, 1970, UTC + MillisecondsSinceEpoch *int64 `protobuf:"varint,5,opt,name=milliseconds_since_epoch,json=millisecondsSinceEpoch" json:"milliseconds_since_epoch,omitempty"` + // Output only. + SystemMetadata *anypb.Any `protobuf:"bytes,6,opt,name=system_metadata,json=systemMetadata" json:"system_metadata,omitempty"` +} + +func (x *Event) Reset() { + *x = Event{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Event) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event) ProtoMessage() {} + +func (x *Event) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Event.ProtoReflect.Descriptor instead. +func (*Event) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{4} +} + +func (x *Event) GetArtifactId() int64 { + if x != nil && x.ArtifactId != nil { + return *x.ArtifactId + } + return 0 +} + +func (x *Event) GetExecutionId() int64 { + if x != nil && x.ExecutionId != nil { + return *x.ExecutionId + } + return 0 +} + +func (x *Event) GetPath() *Event_Path { + if x != nil { + return x.Path + } + return nil +} + +func (x *Event) GetType() Event_Type { + if x != nil && x.Type != nil { + return *x.Type + } + return Event_UNKNOWN +} + +func (x *Event) GetMillisecondsSinceEpoch() int64 { + if x != nil && x.MillisecondsSinceEpoch != nil { + return *x.MillisecondsSinceEpoch + } + return 0 +} + +func (x *Event) GetSystemMetadata() *anypb.Any { + if x != nil { + return x.SystemMetadata + } + return nil +} + +type Execution struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Output only. The unique server generated id of the execution. + Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + // The client provided name of the execution. This field is optional. If set, + // it must be unique among all the executions of the same execution type + // within a database instance and cannot be changed once set. + Name *string `protobuf:"bytes,6,opt,name=name" json:"name,omitempty"` + // The id of an ExecutionType. This needs to be specified when an execution is + // created, and it cannot be changed. + // The id of an ExecutionType. + TypeId *int64 `protobuf:"varint,2,opt,name=type_id,json=typeId" json:"type_id,omitempty"` + // Output only. The name of an ExecutionType. + Type *string `protobuf:"bytes,7,opt,name=type" json:"type,omitempty"` + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all executions within a database instance. + ExternalId *string `protobuf:"bytes,10,opt,name=external_id,json=externalId" json:"external_id,omitempty"` + // The last known state of an execution in the system. + LastKnownState *Execution_State `protobuf:"varint,3,opt,name=last_known_state,json=lastKnownState,enum=ml_metadata.Execution_State" json:"last_known_state,omitempty"` + // Properties of the Execution. + // Properties must be specified in the ExecutionType. + Properties map[string]*Value `protobuf:"bytes,4,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // User provided custom properties which are not defined by its type. + CustomProperties map[string]*Value `protobuf:"bytes,5,rep,name=custom_properties,json=customProperties" json:"custom_properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Output only. Create time of the execution in millisecond since epoch. + CreateTimeSinceEpoch *int64 `protobuf:"varint,8,opt,name=create_time_since_epoch,json=createTimeSinceEpoch" json:"create_time_since_epoch,omitempty"` + // Output only. Last update time of the execution in millisecond since epoch. + LastUpdateTimeSinceEpoch *int64 `protobuf:"varint,9,opt,name=last_update_time_since_epoch,json=lastUpdateTimeSinceEpoch" json:"last_update_time_since_epoch,omitempty"` + // Output only. + SystemMetadata *anypb.Any `protobuf:"bytes,11,opt,name=system_metadata,json=systemMetadata" json:"system_metadata,omitempty"` +} + +func (x *Execution) Reset() { + *x = Execution{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Execution) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Execution) ProtoMessage() {} + +func (x *Execution) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Execution.ProtoReflect.Descriptor instead. +func (*Execution) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{5} +} + +func (x *Execution) GetId() int64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *Execution) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *Execution) GetTypeId() int64 { + if x != nil && x.TypeId != nil { + return *x.TypeId + } + return 0 +} + +func (x *Execution) GetType() string { + if x != nil && x.Type != nil { + return *x.Type + } + return "" +} + +func (x *Execution) GetExternalId() string { + if x != nil && x.ExternalId != nil { + return *x.ExternalId + } + return "" +} + +func (x *Execution) GetLastKnownState() Execution_State { + if x != nil && x.LastKnownState != nil { + return *x.LastKnownState + } + return Execution_UNKNOWN +} + +func (x *Execution) GetProperties() map[string]*Value { + if x != nil { + return x.Properties + } + return nil +} + +func (x *Execution) GetCustomProperties() map[string]*Value { + if x != nil { + return x.CustomProperties + } + return nil +} + +func (x *Execution) GetCreateTimeSinceEpoch() int64 { + if x != nil && x.CreateTimeSinceEpoch != nil { + return *x.CreateTimeSinceEpoch + } + return 0 +} + +func (x *Execution) GetLastUpdateTimeSinceEpoch() int64 { + if x != nil && x.LastUpdateTimeSinceEpoch != nil { + return *x.LastUpdateTimeSinceEpoch + } + return 0 +} + +func (x *Execution) GetSystemMetadata() *anypb.Any { + if x != nil { + return x.SystemMetadata + } + return nil +} + +type ExecutionType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The id of the type. 1-1 relationship between type names and IDs. + Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + // The name of the type. It must be unique among ExecutionTypes within a + // database instance. + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // An optional version of the type. An empty string is treated as unset. + Version *string `protobuf:"bytes,6,opt,name=version" json:"version,omitempty"` + // An optional description about the type. + Description *string `protobuf:"bytes,7,opt,name=description" json:"description,omitempty"` + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all execution types within a database + // instance. + ExternalId *string `protobuf:"bytes,9,opt,name=external_id,json=externalId" json:"external_id,omitempty"` + // The schema of the type. + // Properties are always optional in the execution. + Properties map[string]PropertyType `protobuf:"bytes,3,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=ml_metadata.PropertyType"` + // The ArtifactStructType of the input. + // + // For example: { + // "dict":{ + // "properties":{ + // "schema":{ + // "union_type":{ + // "none":{}, + // "simple":{...schema type...} + // }, + // }, + // "data":{ + // "simple":{...data_type...} + // } + // } + // } + // } + // + // That would be an optional schema field with a required data field. + InputType *ArtifactStructType `protobuf:"bytes,4,opt,name=input_type,json=inputType" json:"input_type,omitempty"` + // The ArtifactStructType of the output. + // For example {"simple":{...stats gen output type...}} + OutputType *ArtifactStructType `protobuf:"bytes,5,opt,name=output_type,json=outputType" json:"output_type,omitempty"` + // An optional system defined base_type expressing the intent of the current + // type. This field is useful for the tool builders to utilize the stored MLMD + // information, e.g., `MyTrainer` ExecutionType could set base_type = TRAIN. + BaseType *ExecutionType_SystemDefinedBaseType `protobuf:"varint,8,opt,name=base_type,json=baseType,enum=ml_metadata.ExecutionType_SystemDefinedBaseType" json:"base_type,omitempty"` +} + +func (x *ExecutionType) Reset() { + *x = ExecutionType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ExecutionType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ExecutionType) ProtoMessage() {} + +func (x *ExecutionType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ExecutionType.ProtoReflect.Descriptor instead. +func (*ExecutionType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{6} +} + +func (x *ExecutionType) GetId() int64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *ExecutionType) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *ExecutionType) GetVersion() string { + if x != nil && x.Version != nil { + return *x.Version + } + return "" +} + +func (x *ExecutionType) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *ExecutionType) GetExternalId() string { + if x != nil && x.ExternalId != nil { + return *x.ExternalId + } + return "" +} + +func (x *ExecutionType) GetProperties() map[string]PropertyType { + if x != nil { + return x.Properties + } + return nil +} + +func (x *ExecutionType) GetInputType() *ArtifactStructType { + if x != nil { + return x.InputType + } + return nil +} + +func (x *ExecutionType) GetOutputType() *ArtifactStructType { + if x != nil { + return x.OutputType + } + return nil +} + +func (x *ExecutionType) GetBaseType() ExecutionType_SystemDefinedBaseType { + if x != nil && x.BaseType != nil { + return *x.BaseType + } + return ExecutionType_UNSET +} + +type ContextType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The id of the type. 1-1 relationship between type names and IDs. + Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + // The name of the type, e.g., Pipeline, Task, Session, User, etc. It must be + // unique among ContextTypes within a database instance. + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + // An optional version of the type. An empty string is treated as unset. + Version *string `protobuf:"bytes,4,opt,name=version" json:"version,omitempty"` + // An optional description about the type. + Description *string `protobuf:"bytes,5,opt,name=description" json:"description,omitempty"` + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all context types within a database + // instance. + ExternalId *string `protobuf:"bytes,7,opt,name=external_id,json=externalId" json:"external_id,omitempty"` + // The schema of the type, e.g., name: string, owner: string + // Properties are always optional in the context. + // Properties of an context type can be expanded but not contracted (i.e., + // you can add columns but not remove them). + Properties map[string]PropertyType `protobuf:"bytes,3,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value,enum=ml_metadata.PropertyType"` + // An optional system defined base_type expressing the intent of the current + // context type. + // *NOTE: currently there are no system Context types defined, and the field + // is not used for ContextType. + BaseType *ContextType_SystemDefinedBaseType `protobuf:"varint,6,opt,name=base_type,json=baseType,enum=ml_metadata.ContextType_SystemDefinedBaseType" json:"base_type,omitempty"` +} + +func (x *ContextType) Reset() { + *x = ContextType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ContextType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ContextType) ProtoMessage() {} + +func (x *ContextType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ContextType.ProtoReflect.Descriptor instead. +func (*ContextType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{7} +} + +func (x *ContextType) GetId() int64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *ContextType) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *ContextType) GetVersion() string { + if x != nil && x.Version != nil { + return *x.Version + } + return "" +} + +func (x *ContextType) GetDescription() string { + if x != nil && x.Description != nil { + return *x.Description + } + return "" +} + +func (x *ContextType) GetExternalId() string { + if x != nil && x.ExternalId != nil { + return *x.ExternalId + } + return "" +} + +func (x *ContextType) GetProperties() map[string]PropertyType { + if x != nil { + return x.Properties + } + return nil +} + +func (x *ContextType) GetBaseType() ContextType_SystemDefinedBaseType { + if x != nil && x.BaseType != nil { + return *x.BaseType + } + return ContextType_UNSET +} + +type Context struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Output Only. The unique server generated id of the context. + Id *int64 `protobuf:"varint,1,opt,name=id" json:"id,omitempty"` + // The client provided name of the context. It must be unique within a + // database instance. + Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + // The id of a ContextType. This needs to be specified when a context is + // created, and it cannot be changed. + TypeId *int64 `protobuf:"varint,2,opt,name=type_id,json=typeId" json:"type_id,omitempty"` + // Output only. The name of a ContextType. + Type *string `protobuf:"bytes,6,opt,name=type" json:"type,omitempty"` + // The external id that come from the clients’ system. This field is optional. + // If set, it must be unique among all contexts within a virtual database. + ExternalId *string `protobuf:"bytes,9,opt,name=external_id,json=externalId" json:"external_id,omitempty"` + // Values of the properties, which must be specified in the ContextType. + Properties map[string]*Value `protobuf:"bytes,4,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // User provided custom properties which are not defined by its type. + CustomProperties map[string]*Value `protobuf:"bytes,5,rep,name=custom_properties,json=customProperties" json:"custom_properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Output only. Create time of the context in millisecond since epoch. + CreateTimeSinceEpoch *int64 `protobuf:"varint,7,opt,name=create_time_since_epoch,json=createTimeSinceEpoch" json:"create_time_since_epoch,omitempty"` + // Output only. Last update time of the context in millisecond since epoch. + LastUpdateTimeSinceEpoch *int64 `protobuf:"varint,8,opt,name=last_update_time_since_epoch,json=lastUpdateTimeSinceEpoch" json:"last_update_time_since_epoch,omitempty"` + // Output only system metadata. + SystemMetadata *anypb.Any `protobuf:"bytes,10,opt,name=system_metadata,json=systemMetadata" json:"system_metadata,omitempty"` +} + +func (x *Context) Reset() { + *x = Context{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Context) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Context) ProtoMessage() {} + +func (x *Context) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Context.ProtoReflect.Descriptor instead. +func (*Context) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{8} +} + +func (x *Context) GetId() int64 { + if x != nil && x.Id != nil { + return *x.Id + } + return 0 +} + +func (x *Context) GetName() string { + if x != nil && x.Name != nil { + return *x.Name + } + return "" +} + +func (x *Context) GetTypeId() int64 { + if x != nil && x.TypeId != nil { + return *x.TypeId + } + return 0 +} + +func (x *Context) GetType() string { + if x != nil && x.Type != nil { + return *x.Type + } + return "" +} + +func (x *Context) GetExternalId() string { + if x != nil && x.ExternalId != nil { + return *x.ExternalId + } + return "" +} + +func (x *Context) GetProperties() map[string]*Value { + if x != nil { + return x.Properties + } + return nil +} + +func (x *Context) GetCustomProperties() map[string]*Value { + if x != nil { + return x.CustomProperties + } + return nil +} + +func (x *Context) GetCreateTimeSinceEpoch() int64 { + if x != nil && x.CreateTimeSinceEpoch != nil { + return *x.CreateTimeSinceEpoch + } + return 0 +} + +func (x *Context) GetLastUpdateTimeSinceEpoch() int64 { + if x != nil && x.LastUpdateTimeSinceEpoch != nil { + return *x.LastUpdateTimeSinceEpoch + } + return 0 +} + +func (x *Context) GetSystemMetadata() *anypb.Any { + if x != nil { + return x.SystemMetadata + } + return nil +} + +// the Attribution edges between Context and Artifact instances. +type Attribution struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ArtifactId *int64 `protobuf:"varint,1,opt,name=artifact_id,json=artifactId" json:"artifact_id,omitempty"` + ContextId *int64 `protobuf:"varint,2,opt,name=context_id,json=contextId" json:"context_id,omitempty"` +} + +func (x *Attribution) Reset() { + *x = Attribution{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Attribution) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Attribution) ProtoMessage() {} + +func (x *Attribution) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Attribution.ProtoReflect.Descriptor instead. +func (*Attribution) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{9} +} + +func (x *Attribution) GetArtifactId() int64 { + if x != nil && x.ArtifactId != nil { + return *x.ArtifactId + } + return 0 +} + +func (x *Attribution) GetContextId() int64 { + if x != nil && x.ContextId != nil { + return *x.ContextId + } + return 0 +} + +// the Association edges between Context and Execution instances. +type Association struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId *int64 `protobuf:"varint,1,opt,name=execution_id,json=executionId" json:"execution_id,omitempty"` + ContextId *int64 `protobuf:"varint,2,opt,name=context_id,json=contextId" json:"context_id,omitempty"` +} + +func (x *Association) Reset() { + *x = Association{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Association) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Association) ProtoMessage() {} + +func (x *Association) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Association.ProtoReflect.Descriptor instead. +func (*Association) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{10} +} + +func (x *Association) GetExecutionId() int64 { + if x != nil && x.ExecutionId != nil { + return *x.ExecutionId + } + return 0 +} + +func (x *Association) GetContextId() int64 { + if x != nil && x.ContextId != nil { + return *x.ContextId + } + return 0 +} + +// the Parental Context edges between Context and Context instances. +type ParentContext struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChildId *int64 `protobuf:"varint,1,opt,name=child_id,json=childId" json:"child_id,omitempty"` + ParentId *int64 `protobuf:"varint,2,opt,name=parent_id,json=parentId" json:"parent_id,omitempty"` +} + +func (x *ParentContext) Reset() { + *x = ParentContext{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ParentContext) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ParentContext) ProtoMessage() {} + +func (x *ParentContext) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ParentContext.ProtoReflect.Descriptor instead. +func (*ParentContext) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{11} +} + +func (x *ParentContext) GetChildId() int64 { + if x != nil && x.ChildId != nil { + return *x.ChildId + } + return 0 +} + +func (x *ParentContext) GetParentId() int64 { + if x != nil && x.ParentId != nil { + return *x.ParentId + } + return 0 +} + +// A self-contained provenance (sub)graph representation consists of MLMD nodes +// and their relationships. It is used to represent the query results from the +// persistent backend (e.g., lineage about a node, reachability of two nodes). +type LineageGraph struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // extracted types + ArtifactTypes []*ArtifactType `protobuf:"bytes,1,rep,name=artifact_types,json=artifactTypes" json:"artifact_types,omitempty"` + ExecutionTypes []*ExecutionType `protobuf:"bytes,2,rep,name=execution_types,json=executionTypes" json:"execution_types,omitempty"` + ContextTypes []*ContextType `protobuf:"bytes,3,rep,name=context_types,json=contextTypes" json:"context_types,omitempty"` + // extracted nodes + Artifacts []*Artifact `protobuf:"bytes,4,rep,name=artifacts" json:"artifacts,omitempty"` + Executions []*Execution `protobuf:"bytes,5,rep,name=executions" json:"executions,omitempty"` + Contexts []*Context `protobuf:"bytes,6,rep,name=contexts" json:"contexts,omitempty"` + // extracted edges + Events []*Event `protobuf:"bytes,7,rep,name=events" json:"events,omitempty"` + Attributions []*Attribution `protobuf:"bytes,8,rep,name=attributions" json:"attributions,omitempty"` + Associations []*Association `protobuf:"bytes,9,rep,name=associations" json:"associations,omitempty"` +} + +func (x *LineageGraph) Reset() { + *x = LineageGraph{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineageGraph) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineageGraph) ProtoMessage() {} + +func (x *LineageGraph) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LineageGraph.ProtoReflect.Descriptor instead. +func (*LineageGraph) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{12} +} + +func (x *LineageGraph) GetArtifactTypes() []*ArtifactType { + if x != nil { + return x.ArtifactTypes + } + return nil +} + +func (x *LineageGraph) GetExecutionTypes() []*ExecutionType { + if x != nil { + return x.ExecutionTypes + } + return nil +} + +func (x *LineageGraph) GetContextTypes() []*ContextType { + if x != nil { + return x.ContextTypes + } + return nil +} + +func (x *LineageGraph) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +func (x *LineageGraph) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +func (x *LineageGraph) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +func (x *LineageGraph) GetEvents() []*Event { + if x != nil { + return x.Events + } + return nil +} + +func (x *LineageGraph) GetAttributions() []*Attribution { + if x != nil { + return x.Attributions + } + return nil +} + +func (x *LineageGraph) GetAssociations() []*Association { + if x != nil { + return x.Associations + } + return nil +} + +// The list of ArtifactStruct is EXPERIMENTAL and not in use yet. +// The type of an ArtifactStruct. +// An artifact struct type represents an infinite set of artifact structs. +// It can specify the input or output type of an ExecutionType. +// See the more specific types referenced in the message for more details. +type ArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Kind: + // + // *ArtifactStructType_Simple + // *ArtifactStructType_UnionType + // *ArtifactStructType_Intersection + // *ArtifactStructType_List + // *ArtifactStructType_None + // *ArtifactStructType_Any + // *ArtifactStructType_Tuple + // *ArtifactStructType_Dict + Kind isArtifactStructType_Kind `protobuf_oneof:"kind"` +} + +func (x *ArtifactStructType) Reset() { + *x = ArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArtifactStructType) ProtoMessage() {} + +func (x *ArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArtifactStructType.ProtoReflect.Descriptor instead. +func (*ArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{13} +} + +func (m *ArtifactStructType) GetKind() isArtifactStructType_Kind { + if m != nil { + return m.Kind + } + return nil +} + +func (x *ArtifactStructType) GetSimple() *ArtifactType { + if x, ok := x.GetKind().(*ArtifactStructType_Simple); ok { + return x.Simple + } + return nil +} + +func (x *ArtifactStructType) GetUnionType() *UnionArtifactStructType { + if x, ok := x.GetKind().(*ArtifactStructType_UnionType); ok { + return x.UnionType + } + return nil +} + +func (x *ArtifactStructType) GetIntersection() *IntersectionArtifactStructType { + if x, ok := x.GetKind().(*ArtifactStructType_Intersection); ok { + return x.Intersection + } + return nil +} + +func (x *ArtifactStructType) GetList() *ListArtifactStructType { + if x, ok := x.GetKind().(*ArtifactStructType_List); ok { + return x.List + } + return nil +} + +func (x *ArtifactStructType) GetNone() *NoneArtifactStructType { + if x, ok := x.GetKind().(*ArtifactStructType_None); ok { + return x.None + } + return nil +} + +func (x *ArtifactStructType) GetAny() *AnyArtifactStructType { + if x, ok := x.GetKind().(*ArtifactStructType_Any); ok { + return x.Any + } + return nil +} + +func (x *ArtifactStructType) GetTuple() *TupleArtifactStructType { + if x, ok := x.GetKind().(*ArtifactStructType_Tuple); ok { + return x.Tuple + } + return nil +} + +func (x *ArtifactStructType) GetDict() *DictArtifactStructType { + if x, ok := x.GetKind().(*ArtifactStructType_Dict); ok { + return x.Dict + } + return nil +} + +type isArtifactStructType_Kind interface { + isArtifactStructType_Kind() +} + +type ArtifactStructType_Simple struct { + Simple *ArtifactType `protobuf:"bytes,1,opt,name=simple,oneof"` // Matches exactly this type. +} + +type ArtifactStructType_UnionType struct { + UnionType *UnionArtifactStructType `protobuf:"bytes,2,opt,name=union_type,json=unionType,oneof"` +} + +type ArtifactStructType_Intersection struct { + Intersection *IntersectionArtifactStructType `protobuf:"bytes,3,opt,name=intersection,oneof"` +} + +type ArtifactStructType_List struct { + List *ListArtifactStructType `protobuf:"bytes,4,opt,name=list,oneof"` +} + +type ArtifactStructType_None struct { + None *NoneArtifactStructType `protobuf:"bytes,5,opt,name=none,oneof"` +} + +type ArtifactStructType_Any struct { + Any *AnyArtifactStructType `protobuf:"bytes,6,opt,name=any,oneof"` +} + +type ArtifactStructType_Tuple struct { + Tuple *TupleArtifactStructType `protobuf:"bytes,7,opt,name=tuple,oneof"` +} + +type ArtifactStructType_Dict struct { + Dict *DictArtifactStructType `protobuf:"bytes,8,opt,name=dict,oneof"` +} + +func (*ArtifactStructType_Simple) isArtifactStructType_Kind() {} + +func (*ArtifactStructType_UnionType) isArtifactStructType_Kind() {} + +func (*ArtifactStructType_Intersection) isArtifactStructType_Kind() {} + +func (*ArtifactStructType_List) isArtifactStructType_Kind() {} + +func (*ArtifactStructType_None) isArtifactStructType_Kind() {} + +func (*ArtifactStructType_Any) isArtifactStructType_Kind() {} + +func (*ArtifactStructType_Tuple) isArtifactStructType_Kind() {} + +func (*ArtifactStructType_Dict) isArtifactStructType_Kind() {} + +// Represents a union of types. +type UnionArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // An artifact struct matches this type if it matches any of the candidates. + // If candidates is empty, this is a bottom type (matches no artifacts). + Candidates []*ArtifactStructType `protobuf:"bytes,1,rep,name=candidates" json:"candidates,omitempty"` +} + +func (x *UnionArtifactStructType) Reset() { + *x = UnionArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnionArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnionArtifactStructType) ProtoMessage() {} + +func (x *UnionArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnionArtifactStructType.ProtoReflect.Descriptor instead. +func (*UnionArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{14} +} + +func (x *UnionArtifactStructType) GetCandidates() []*ArtifactStructType { + if x != nil { + return x.Candidates + } + return nil +} + +// A member of this type must satisfy all constraints. +// This primarily useful not as an end-user type, but something calculated +// as an intermediate type in the system. +// +// For example, suppose you have a method: +// def infer_my_input_type(a): # try to infer the input type of this method. +// +// use_in_method_x(a) # with input type x_input +// use_in_method_y(a) # with input type y_input +// +// Given this information, you know that infer_my_input_type has +// type {"intersection":{"constraints":[x_input, y_input]}}. +// +// IntersectionArtifactStructType intersection_type = {"constraints":[ +// +// {"dict":{"properties":{"schema":{"any":{}}}, +// "extra_properties":{"any":{}}}}, +// {"dict":{"properties":{"data":{"any":{}}}, +// "extra_properties":{"any":{}}}}]} +// +// Since the first constraint requires the dictionary to have a schema +// property, and the second constraint requires it to have a data property, this +// is equivalent to: +// ArtifactStructType other_type = +// +// {"dict":{"properties":{"schema":{"any":{}},"data":{"any":{}}}}, +// "extra_properties":{"any":{}}} +type IntersectionArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Constraints []*ArtifactStructType `protobuf:"bytes,1,rep,name=constraints" json:"constraints,omitempty"` +} + +func (x *IntersectionArtifactStructType) Reset() { + *x = IntersectionArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *IntersectionArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*IntersectionArtifactStructType) ProtoMessage() {} + +func (x *IntersectionArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use IntersectionArtifactStructType.ProtoReflect.Descriptor instead. +func (*IntersectionArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{15} +} + +func (x *IntersectionArtifactStructType) GetConstraints() []*ArtifactStructType { + if x != nil { + return x.Constraints + } + return nil +} + +// Represents an ArtifactStruct list type with homogeneous elements. +type ListArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Every entry in the list must be of this type. + // Note: if this type is Any, then the list can have arbitrary elements. + Element *ArtifactStructType `protobuf:"bytes,1,opt,name=element" json:"element,omitempty"` +} + +func (x *ListArtifactStructType) Reset() { + *x = ListArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListArtifactStructType) ProtoMessage() {} + +func (x *ListArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListArtifactStructType.ProtoReflect.Descriptor instead. +func (*ListArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{16} +} + +func (x *ListArtifactStructType) GetElement() *ArtifactStructType { + if x != nil { + return x.Element + } + return nil +} + +// The only member of this type is a None artifact. +// Note: ArtifactStruct{} is a None artifact. +// This can represent an execution that has no outputs (or inputs), +// or can be part of a UnionArtifactStructType to represent an optional +// input. +// For example, StatsGen has an "optional" schema input. +// A practical example of this is: +// +// stats_gen_type = { +// "dict":{ +// "properties":{ +// "schema":{ +// "union_type":{ +// "none":{}, +// "simple":{...schema type...} +// }, +// }, +// "data":{ +// "simple":{...data_type...} +// } +// } +// } +// }; +type NoneArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *NoneArtifactStructType) Reset() { + *x = NoneArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NoneArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NoneArtifactStructType) ProtoMessage() {} + +func (x *NoneArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NoneArtifactStructType.ProtoReflect.Descriptor instead. +func (*NoneArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{17} +} + +// Every ArtifactStruct is a member of this type. +type AnyArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *AnyArtifactStructType) Reset() { + *x = AnyArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AnyArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AnyArtifactStructType) ProtoMessage() {} + +func (x *AnyArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AnyArtifactStructType.ProtoReflect.Descriptor instead. +func (*AnyArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{18} +} + +// An ordered list of heterogeneous artifact structs. +// The length of the list is fixed. +// Each position in the list can have a different type. +type TupleArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Elements []*ArtifactStructType `protobuf:"bytes,1,rep,name=elements" json:"elements,omitempty"` +} + +func (x *TupleArtifactStructType) Reset() { + *x = TupleArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TupleArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TupleArtifactStructType) ProtoMessage() {} + +func (x *TupleArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TupleArtifactStructType.ProtoReflect.Descriptor instead. +func (*TupleArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{19} +} + +func (x *TupleArtifactStructType) GetElements() []*ArtifactStructType { + if x != nil { + return x.Elements + } + return nil +} + +// A artifact struct type that represents a record or struct-like dictionary. +// ArtifactStruct would be map (i.e. ArtifactStructMap) +type DictArtifactStructType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Underlying properties for the type. + Properties map[string]*ArtifactStructType `protobuf:"bytes,1,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // If true, then if properties["foo"] can be None, then that key is not + // required. + NoneTypeNotRequired *bool `protobuf:"varint,2,opt,name=none_type_not_required,json=noneTypeNotRequired" json:"none_type_not_required,omitempty"` + // Extra keys are allowed that are not specified in properties. These + // keys must have the type specified below. + // If this is not specified, then extra properties are not allowed. + ExtraPropertiesType *ArtifactStructType `protobuf:"bytes,3,opt,name=extra_properties_type,json=extraPropertiesType" json:"extra_properties_type,omitempty"` +} + +func (x *DictArtifactStructType) Reset() { + *x = DictArtifactStructType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DictArtifactStructType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DictArtifactStructType) ProtoMessage() {} + +func (x *DictArtifactStructType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DictArtifactStructType.ProtoReflect.Descriptor instead. +func (*DictArtifactStructType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{20} +} + +func (x *DictArtifactStructType) GetProperties() map[string]*ArtifactStructType { + if x != nil { + return x.Properties + } + return nil +} + +func (x *DictArtifactStructType) GetNoneTypeNotRequired() bool { + if x != nil && x.NoneTypeNotRequired != nil { + return *x.NoneTypeNotRequired + } + return false +} + +func (x *DictArtifactStructType) GetExtraPropertiesType() *ArtifactStructType { + if x != nil { + return x.ExtraPropertiesType + } + return nil +} + +// Configuration for a "fake" database. +// This database is an in-memory SQLite database that lives only as +// long as the associated object lives. +type FakeDatabaseConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FakeDatabaseConfig) Reset() { + *x = FakeDatabaseConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FakeDatabaseConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FakeDatabaseConfig) ProtoMessage() {} + +func (x *FakeDatabaseConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FakeDatabaseConfig.ProtoReflect.Descriptor instead. +func (*FakeDatabaseConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{21} +} + +type MySQLDatabaseConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The hostname or IP address of the MYSQL server: + // - If unspecified, a connection to the local host is assumed. + // The client connects using a Unix socket specified by `socket`. + // - Otherwise, TCP/IP is used. + // + // Currently a replicated MYSQL backend is not supported. + Host *string `protobuf:"bytes,1,opt,name=host" json:"host,omitempty"` + // The TCP Port number that the MYSQL server accepts connections on. + // If unspecified, the default MYSQL port (3306) is used. + Port *int64 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` + // The database to connect to. Must be specified. + // After connecting to the MYSQL server, this database is created if not + // already present unless skip_db_creation is set. + // All queries after Connect() are assumed to be for this database. + Database *string `protobuf:"bytes,3,opt,name=database" json:"database,omitempty"` + // The MYSQL login id. If empty, the current user is assumed. + User *string `protobuf:"bytes,4,opt,name=user" json:"user,omitempty"` + // The password to use for `user`. If empty, only MYSQL user ids that don't + // have a password set are allowed to connect. + Password *string `protobuf:"bytes,5,opt,name=password" json:"password,omitempty"` + // The Unix socket to use to connect to the server. If unspecified, a + // `host` must be provided. + Socket *string `protobuf:"bytes,6,opt,name=socket" json:"socket,omitempty"` + // If the field is set, the ssl options are set in mysql_options before + // establishing a connection. It is ignored if the mysql server does not + // enable SSL. + SslOptions *MySQLDatabaseConfig_SSLOptions `protobuf:"bytes,7,opt,name=ssl_options,json=sslOptions" json:"ssl_options,omitempty"` + // A config to skip the database creation if not exist when connecting the + // db instance. It is useful when the db creation is handled by an admin + // process, while the lib user should not issue db creation clauses. + SkipDbCreation *bool `protobuf:"varint,8,opt,name=skip_db_creation,json=skipDbCreation" json:"skip_db_creation,omitempty"` +} + +func (x *MySQLDatabaseConfig) Reset() { + *x = MySQLDatabaseConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MySQLDatabaseConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MySQLDatabaseConfig) ProtoMessage() {} + +func (x *MySQLDatabaseConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MySQLDatabaseConfig.ProtoReflect.Descriptor instead. +func (*MySQLDatabaseConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{22} +} + +func (x *MySQLDatabaseConfig) GetHost() string { + if x != nil && x.Host != nil { + return *x.Host + } + return "" +} + +func (x *MySQLDatabaseConfig) GetPort() int64 { + if x != nil && x.Port != nil { + return *x.Port + } + return 0 +} + +func (x *MySQLDatabaseConfig) GetDatabase() string { + if x != nil && x.Database != nil { + return *x.Database + } + return "" +} + +func (x *MySQLDatabaseConfig) GetUser() string { + if x != nil && x.User != nil { + return *x.User + } + return "" +} + +func (x *MySQLDatabaseConfig) GetPassword() string { + if x != nil && x.Password != nil { + return *x.Password + } + return "" +} + +func (x *MySQLDatabaseConfig) GetSocket() string { + if x != nil && x.Socket != nil { + return *x.Socket + } + return "" +} + +func (x *MySQLDatabaseConfig) GetSslOptions() *MySQLDatabaseConfig_SSLOptions { + if x != nil { + return x.SslOptions + } + return nil +} + +func (x *MySQLDatabaseConfig) GetSkipDbCreation() bool { + if x != nil && x.SkipDbCreation != nil { + return *x.SkipDbCreation + } + return false +} + +// A config contains the parameters when using with SqliteMetadatSource. +type SqliteMetadataSourceConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A uri specifying Sqlite3 database filename, for example: + // + // file:some_sqlite3_file_in_local_dir.db + // file:///home/username/some_sqlite3_file.db + // + // see https://www.sqlite.org/c3ref/open.html for model details + // + // If not given, a in-memory sqlite3 database is used, and destroyed when + // disconnecting the metadata source. + FilenameUri *string `protobuf:"bytes,1,opt,name=filename_uri,json=filenameUri" json:"filename_uri,omitempty"` + // A flag specifying the connection mode. If not given, default connection + // mode is set to READWRITE_OPENCREATE. + ConnectionMode *SqliteMetadataSourceConfig_ConnectionMode `protobuf:"varint,2,opt,name=connection_mode,json=connectionMode,enum=ml_metadata.SqliteMetadataSourceConfig_ConnectionMode" json:"connection_mode,omitempty"` +} + +func (x *SqliteMetadataSourceConfig) Reset() { + *x = SqliteMetadataSourceConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SqliteMetadataSourceConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SqliteMetadataSourceConfig) ProtoMessage() {} + +func (x *SqliteMetadataSourceConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SqliteMetadataSourceConfig.ProtoReflect.Descriptor instead. +func (*SqliteMetadataSourceConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{23} +} + +func (x *SqliteMetadataSourceConfig) GetFilenameUri() string { + if x != nil && x.FilenameUri != nil { + return *x.FilenameUri + } + return "" +} + +func (x *SqliteMetadataSourceConfig) GetConnectionMode() SqliteMetadataSourceConfig_ConnectionMode { + if x != nil && x.ConnectionMode != nil { + return *x.ConnectionMode + } + return SqliteMetadataSourceConfig_UNKNOWN +} + +// A config contains the parameters when using with PostgreSQLMetadatSource. +// Next index: 10 +type PostgreSQLDatabaseConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of host to connect to. If the host name starts with /, it is taken as + // a Unix-domain socket in the abstract namespace. + Host *string `protobuf:"bytes,1,opt,name=host" json:"host,omitempty"` + // Numeric IP address of host to connect to. If this field is provided, `host` + // field is ignored. + Hostaddr *string `protobuf:"bytes,2,opt,name=hostaddr" json:"hostaddr,omitempty"` + // Port number to connect to at the server host, or socket file name extension + // for Unix-domain connections. + Port *string `protobuf:"bytes,3,opt,name=port" json:"port,omitempty"` + // PostgreSQL user name to connect as. Defaults to be the same as the + // operating system name of the user running the application. + User *string `protobuf:"bytes,4,opt,name=user" json:"user,omitempty"` + // Password to be used if the server demands password authentication. + Password *string `protobuf:"bytes,5,opt,name=password" json:"password,omitempty"` + // Specifies the name of the file used to store passwords. + Passfile *string `protobuf:"bytes,6,opt,name=passfile" json:"passfile,omitempty"` + // The database name. Defaults to be the same as the user name. + Dbname *string `protobuf:"bytes,7,opt,name=dbname" json:"dbname,omitempty"` + // A config to skip the database creation if not exist when connecting the + // db instance. It is useful when the db creation is handled by an admin + // process, while the lib user should not issue db creation clauses. + SkipDbCreation *bool `protobuf:"varint,8,opt,name=skip_db_creation,json=skipDbCreation" json:"skip_db_creation,omitempty"` + Ssloption *PostgreSQLDatabaseConfig_SSLOptions `protobuf:"bytes,9,opt,name=ssloption" json:"ssloption,omitempty"` +} + +func (x *PostgreSQLDatabaseConfig) Reset() { + *x = PostgreSQLDatabaseConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PostgreSQLDatabaseConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PostgreSQLDatabaseConfig) ProtoMessage() {} + +func (x *PostgreSQLDatabaseConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PostgreSQLDatabaseConfig.ProtoReflect.Descriptor instead. +func (*PostgreSQLDatabaseConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{24} +} + +func (x *PostgreSQLDatabaseConfig) GetHost() string { + if x != nil && x.Host != nil { + return *x.Host + } + return "" +} + +func (x *PostgreSQLDatabaseConfig) GetHostaddr() string { + if x != nil && x.Hostaddr != nil { + return *x.Hostaddr + } + return "" +} + +func (x *PostgreSQLDatabaseConfig) GetPort() string { + if x != nil && x.Port != nil { + return *x.Port + } + return "" +} + +func (x *PostgreSQLDatabaseConfig) GetUser() string { + if x != nil && x.User != nil { + return *x.User + } + return "" +} + +func (x *PostgreSQLDatabaseConfig) GetPassword() string { + if x != nil && x.Password != nil { + return *x.Password + } + return "" +} + +func (x *PostgreSQLDatabaseConfig) GetPassfile() string { + if x != nil && x.Passfile != nil { + return *x.Passfile + } + return "" +} + +func (x *PostgreSQLDatabaseConfig) GetDbname() string { + if x != nil && x.Dbname != nil { + return *x.Dbname + } + return "" +} + +func (x *PostgreSQLDatabaseConfig) GetSkipDbCreation() bool { + if x != nil && x.SkipDbCreation != nil { + return *x.SkipDbCreation + } + return false +} + +func (x *PostgreSQLDatabaseConfig) GetSsloption() *PostgreSQLDatabaseConfig_SSLOptions { + if x != nil { + return x.Ssloption + } + return nil +} + +type MigrationOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // If not set, by default the upgrade migration is disabled. MLMD only + // compares db_v with the lib_v, and raise error if the two do not align. + // If the field is set to true, MLMD performs upgrade migration. It upgrades + // the database schema version (db_v) to align with the library schema + // version (lib_v) when connecting to the database. + // Schema migration should not be run concurrently with multiple clients to + // prevent data races. + EnableUpgradeMigration *bool `protobuf:"varint,3,opt,name=enable_upgrade_migration,json=enableUpgradeMigration" json:"enable_upgrade_migration,omitempty"` + // Downgrade the given database to the specified schema version. + // For v0.13.2 release, the schema_version is 0. + // For 0.14.0 and 0.15.0 release, the schema_version is 4. + // More details are described in g3doc/get_start.md#upgrade-mlmd-library + // Set this field only when a database is accidentally upgraded by a newer + // version library. Each library version only knows how to downgrade to + // previous schema versions. As downgrade migrations inevitably introduce + // data loss, please consider taking a backup of the database before + // downgrading schema. + // After downgrade migration, the database connection is canceled. The user + // needs to downgrade the library to use the database. + DowngradeToSchemaVersion *int64 `protobuf:"varint,2,opt,name=downgrade_to_schema_version,json=downgradeToSchemaVersion,def=-1" json:"downgrade_to_schema_version,omitempty"` +} + +// Default values for MigrationOptions fields. +const ( + Default_MigrationOptions_DowngradeToSchemaVersion = int64(-1) +) + +func (x *MigrationOptions) Reset() { + *x = MigrationOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MigrationOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MigrationOptions) ProtoMessage() {} + +func (x *MigrationOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MigrationOptions.ProtoReflect.Descriptor instead. +func (*MigrationOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{25} +} + +func (x *MigrationOptions) GetEnableUpgradeMigration() bool { + if x != nil && x.EnableUpgradeMigration != nil { + return *x.EnableUpgradeMigration + } + return false +} + +func (x *MigrationOptions) GetDowngradeToSchemaVersion() int64 { + if x != nil && x.DowngradeToSchemaVersion != nil { + return *x.DowngradeToSchemaVersion + } + return Default_MigrationOptions_DowngradeToSchemaVersion +} + +type RetryOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The max number of retries when transaction returns Aborted error. + MaxNumRetries *int64 `protobuf:"varint,1,opt,name=max_num_retries,json=maxNumRetries" json:"max_num_retries,omitempty"` +} + +func (x *RetryOptions) Reset() { + *x = RetryOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RetryOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RetryOptions) ProtoMessage() {} + +func (x *RetryOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RetryOptions.ProtoReflect.Descriptor instead. +func (*RetryOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{26} +} + +func (x *RetryOptions) GetMaxNumRetries() int64 { + if x != nil && x.MaxNumRetries != nil { + return *x.MaxNumRetries + } + return 0 +} + +type ConnectionConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Configuration for a new connection. + // + // Types that are assignable to Config: + // + // *ConnectionConfig_FakeDatabase + // *ConnectionConfig_Mysql + // *ConnectionConfig_Sqlite + // *ConnectionConfig_Postgresql + Config isConnectionConfig_Config `protobuf_oneof:"config"` + // Options for overwriting the default retry setting when MLMD transactions + // returning Aborted error. + // The setting is currently available for python client library only. + // TODO(b/154862807) set the setting in transaction executor. + RetryOptions *RetryOptions `protobuf:"bytes,4,opt,name=retry_options,json=retryOptions" json:"retry_options,omitempty"` +} + +func (x *ConnectionConfig) Reset() { + *x = ConnectionConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnectionConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectionConfig) ProtoMessage() {} + +func (x *ConnectionConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectionConfig.ProtoReflect.Descriptor instead. +func (*ConnectionConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{27} +} + +func (m *ConnectionConfig) GetConfig() isConnectionConfig_Config { + if m != nil { + return m.Config + } + return nil +} + +func (x *ConnectionConfig) GetFakeDatabase() *FakeDatabaseConfig { + if x, ok := x.GetConfig().(*ConnectionConfig_FakeDatabase); ok { + return x.FakeDatabase + } + return nil +} + +func (x *ConnectionConfig) GetMysql() *MySQLDatabaseConfig { + if x, ok := x.GetConfig().(*ConnectionConfig_Mysql); ok { + return x.Mysql + } + return nil +} + +func (x *ConnectionConfig) GetSqlite() *SqliteMetadataSourceConfig { + if x, ok := x.GetConfig().(*ConnectionConfig_Sqlite); ok { + return x.Sqlite + } + return nil +} + +func (x *ConnectionConfig) GetPostgresql() *PostgreSQLDatabaseConfig { + if x, ok := x.GetConfig().(*ConnectionConfig_Postgresql); ok { + return x.Postgresql + } + return nil +} + +func (x *ConnectionConfig) GetRetryOptions() *RetryOptions { + if x != nil { + return x.RetryOptions + } + return nil +} + +type isConnectionConfig_Config interface { + isConnectionConfig_Config() +} + +type ConnectionConfig_FakeDatabase struct { + FakeDatabase *FakeDatabaseConfig `protobuf:"bytes,1,opt,name=fake_database,json=fakeDatabase,oneof"` +} + +type ConnectionConfig_Mysql struct { + Mysql *MySQLDatabaseConfig `protobuf:"bytes,2,opt,name=mysql,oneof"` +} + +type ConnectionConfig_Sqlite struct { + Sqlite *SqliteMetadataSourceConfig `protobuf:"bytes,3,opt,name=sqlite,oneof"` +} + +type ConnectionConfig_Postgresql struct { + // PostgreSQL database connection config. + Postgresql *PostgreSQLDatabaseConfig `protobuf:"bytes,5,opt,name=postgresql,oneof"` +} + +func (*ConnectionConfig_FakeDatabase) isConnectionConfig_Config() {} + +func (*ConnectionConfig_Mysql) isConnectionConfig_Config() {} + +func (*ConnectionConfig_Sqlite) isConnectionConfig_Config() {} + +func (*ConnectionConfig_Postgresql) isConnectionConfig_Config() {} + +// A list of supported GRPC arguments defined in: +// https://grpc.github.io/grpc/core/group__grpc__arg__keys.html +type GrpcChannelArguments struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Maximum message length in bytes per response that the channel can receive. + MaxReceiveMessageLength *int64 `protobuf:"varint,1,opt,name=max_receive_message_length,json=maxReceiveMessageLength" json:"max_receive_message_length,omitempty"` + // Maximum misbehaving pings the server can bear before sending goaway and + // closing the transport? (0 indicates infinite number of misbehaving pings) + Http2MaxPingStrikes *int64 `protobuf:"varint,2,opt,name=http2_max_ping_strikes,json=http2MaxPingStrikes" json:"http2_max_ping_strikes,omitempty"` +} + +func (x *GrpcChannelArguments) Reset() { + *x = GrpcChannelArguments{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GrpcChannelArguments) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GrpcChannelArguments) ProtoMessage() {} + +func (x *GrpcChannelArguments) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GrpcChannelArguments.ProtoReflect.Descriptor instead. +func (*GrpcChannelArguments) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{28} +} + +func (x *GrpcChannelArguments) GetMaxReceiveMessageLength() int64 { + if x != nil && x.MaxReceiveMessageLength != nil { + return *x.MaxReceiveMessageLength + } + return 0 +} + +func (x *GrpcChannelArguments) GetHttp2MaxPingStrikes() int64 { + if x != nil && x.Http2MaxPingStrikes != nil { + return *x.Http2MaxPingStrikes + } + return 0 +} + +// Configuration for the gRPC metadata store client. +type MetadataStoreClientConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The hostname or IP address of the gRPC server. Must be specified. + Host *string `protobuf:"bytes,1,opt,name=host" json:"host,omitempty"` + // The TCP Port number that the gRPC server accepts connections on. + // Must be specified. + Port *int64 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` + // Configuration for a secure gRPC channel. + // If not given, insecure connection is used. + SslConfig *MetadataStoreClientConfig_SSLConfig `protobuf:"bytes,3,opt,name=ssl_config,json=sslConfig" json:"ssl_config,omitempty"` + // GRPC channel creation arguments. + ChannelArguments *GrpcChannelArguments `protobuf:"bytes,4,opt,name=channel_arguments,json=channelArguments" json:"channel_arguments,omitempty"` + // Time duration that a client is willing to wait for a reply from the server. + // If unset, the timeout is considered infinite. When the field is specified, + // Grpc APIs would return DeadlineExceededError when server does not respond + // within `client_timeout_sec`. Floating point valued, in seconds. + ClientTimeoutSec *float64 `protobuf:"fixed64,5,opt,name=client_timeout_sec,json=clientTimeoutSec" json:"client_timeout_sec,omitempty"` +} + +func (x *MetadataStoreClientConfig) Reset() { + *x = MetadataStoreClientConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MetadataStoreClientConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataStoreClientConfig) ProtoMessage() {} + +func (x *MetadataStoreClientConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataStoreClientConfig.ProtoReflect.Descriptor instead. +func (*MetadataStoreClientConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{29} +} + +func (x *MetadataStoreClientConfig) GetHost() string { + if x != nil && x.Host != nil { + return *x.Host + } + return "" +} + +func (x *MetadataStoreClientConfig) GetPort() int64 { + if x != nil && x.Port != nil { + return *x.Port + } + return 0 +} + +func (x *MetadataStoreClientConfig) GetSslConfig() *MetadataStoreClientConfig_SSLConfig { + if x != nil { + return x.SslConfig + } + return nil +} + +func (x *MetadataStoreClientConfig) GetChannelArguments() *GrpcChannelArguments { + if x != nil { + return x.ChannelArguments + } + return nil +} + +func (x *MetadataStoreClientConfig) GetClientTimeoutSec() float64 { + if x != nil && x.ClientTimeoutSec != nil { + return *x.ClientTimeoutSec + } + return 0 +} + +// Configuration for the gRPC metadata store server. +type MetadataStoreServerConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Configuration to connect the metadata source backend. + ConnectionConfig *ConnectionConfig `protobuf:"bytes,1,opt,name=connection_config,json=connectionConfig" json:"connection_config,omitempty"` + // Configuration for upgrade and downgrade migrations the metadata source. + MigrationOptions *MigrationOptions `protobuf:"bytes,3,opt,name=migration_options,json=migrationOptions" json:"migration_options,omitempty"` + // Configuration for a secure gRPC channel. + // If not given, insecure connection is used. + SslConfig *MetadataStoreServerConfig_SSLConfig `protobuf:"bytes,2,opt,name=ssl_config,json=sslConfig" json:"ssl_config,omitempty"` +} + +func (x *MetadataStoreServerConfig) Reset() { + *x = MetadataStoreServerConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MetadataStoreServerConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataStoreServerConfig) ProtoMessage() {} + +func (x *MetadataStoreServerConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataStoreServerConfig.ProtoReflect.Descriptor instead. +func (*MetadataStoreServerConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{30} +} + +func (x *MetadataStoreServerConfig) GetConnectionConfig() *ConnectionConfig { + if x != nil { + return x.ConnectionConfig + } + return nil +} + +func (x *MetadataStoreServerConfig) GetMigrationOptions() *MigrationOptions { + if x != nil { + return x.MigrationOptions + } + return nil +} + +func (x *MetadataStoreServerConfig) GetSslConfig() *MetadataStoreServerConfig_SSLConfig { + if x != nil { + return x.SslConfig + } + return nil +} + +// ListOperationOptions represents the set of options and predicates to be +// used for List operations on Artifacts, Executions and Contexts. +type ListOperationOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Max number of resources to return in the result. A value of zero or less + // results in a InvalidArgumentError. + // The API implementation also enforces an upper-bound of 100, and picks the + // minimum between this value and the one specified here. + MaxResultSize *int32 `protobuf:"varint,1,opt,name=max_result_size,json=maxResultSize,def=20" json:"max_result_size,omitempty"` + // Ordering field. + OrderByField *ListOperationOptions_OrderByField `protobuf:"bytes,2,opt,name=order_by_field,json=orderByField" json:"order_by_field,omitempty"` + // Identifies the next page of results. + NextPageToken *string `protobuf:"bytes,3,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` + // A boolean expression in SQL syntax that is used to specify the conditions + // on node attributes and directly connected assets. + // + // In the current implementation, filtering Artifact/Execution/Context with + // the following attributes and neighborhood is supported: + // + // Attributes: + // + // id:int64, type_id:int64, type:string, + // uri:string, name: string, external_id: string, + // create_time_since_epoch:int64, last_update_time_since_epoch:int64 + // state:ENUM (Artifact only) last_known_state:ENUM (Execution only) + // + // Neighborhood + // - Properties and Custom Properties (for all node types): + // syntax: properties.$name ($name is the property name) + // custom_properties.$name ($name is the custom property name) + // attributes: the following attributes can be used + // int_value: int64, double_value: double, string_value: string + // bool_value: bool + // + // - Context (for Artifact and Execution): + // syntax: contexts_$alias ($alias can be [0-9A-Za-z_]) + // attributes: the following attributes can be used + // id:int64, name:string, type:string, create_time_since_epoch:int64, + // last_update_time_since_epoch: int64 + // + // - Parent and Child Contexts (for Contexts): + // syntax: parent_contexts_$alias( $alias can be [0-9A-Za-z_] + // child_contexts_$alias( $alias can be [0-9A-Za-z_] + // attributes: the following attributes can be used + // id:int64, name: string, type:string + // + // - Event (for Artifact and Execution) + // syntax: events_$alias ($alias can be [0-9A-Za-z_]) + // attributes: the following attributes can be used + // artifact_id: int64(Execution only), execution_id: int64(Artifact only), + // type: ENUM, milliseconds_since_epoch: int64 + // + // Examples: + // a) to filter nodes attributes: + // - id != 1 + // - id IN (1, 3) + // - type_id = 5 + // - type = 'my_type_name' + // - name = 'foo' + // - type = 'bar' AND name LIKE 'foo%' + // - external_id = 'my_external_id' + // - NOT(create_time_since_epoch < 1 OR last_update_time_since_epoch < 1) + // + // b) to filter artifacts' uri + // - uri = 'exact_path_string' + // - uri LIKE 'path_like_this%' + // - uri IS NOT NULL + // + // c) to filter artifact's state or execution's last_known_state + // - state = LIVE + // - state IS NULL + // - state IN (PENDING, LIVE) + // - last_known_state = RUNNING + // - last_known_state != RUNNING + // - last_known_state NOT IN (FAILED, CANCELED) + // + // d) to filter nodes having a specific context, artifact, or execution + // - contexts_a.id = 5 + // - contexts_a.type = 'RunContext' + // - contexts_a.name = 'my_run' + // - contexts_a.create_time_since_epoch = 1626761453 + // - contexts_a.last_update_time_since_epoch = 1626761453 + // To filter nodes with conditions on multiple contexts: + // - contexts_a.name = 'my_run' AND contexts_b.name = 'my_pipeline' + // To filter context with artifacts: + // - artifacts_a.id = 5 + // - artifacts_a.type = 'Dataset' + // - artifacts_a.name = 'my_dataset' + // - artifacts_a.uri = 'exact_path_string' + // - artifacts_a.state = LIVE + // - artifacts_a.state IN (PENDING, LIVE) + // - artifacts_a.external_id = "my_external_id" + // - artifacts_a.create_time_since_epoch = 1626761453 + // - artifacts_a.last_update_time_since_epoch = 1626761453 + // To filter contexts with conditions on multiple artifacts: + // - artifacts_a.name = 'my_run' AND artifacts_b.name = 'my_pipeline' + // To filter context with executions: + // - executions_a.id = 5 + // - executions_a.type = 'Dataset' + // - executions_a.name = 'my_dataset' + // - executions_a.last_known_state = RUNNING + // + // . - executions_a.last_known_state IN (NEW, RUNNING) + // - executions_a.external_id = "my_external_id" + // - executions_a.create_time_since_epoch = 1626761453 + // - executions_a.last_update_time_since_epoch = 1626761453 + // To filter contexts with conditions on multiple executions: + // - executions_a.name = 'my_run' AND executions_b.name = 'my_pipeline' + // + // e) to filter nodes condition on their properties + // - properties.accuracy.double_value > 0.95 + // - custom_properties.my_param.string_value = "foo" + // If the name of the property or custom property includes characters + // other than [0-9A-Za-z_], then the name need to be backquoted, + // e.g., + // - properties.`my property`.int_value > 0 + // - custom_properties.`my:custom.property`.bool_value = true + // + // f) complex query to filter both node attributes and neighborhood + // - type = 'DataSet' AND + // (contexts_a.type = 'RunContext' AND contexts_a.name = 'my_run') AND + // (properties.span = 1 OR custom_properties.span = 1) + // + // g) to filter parent/child context + // - parent_contexts_a.id = 5 + // - child_contexts_a.type = 'RunContext' + // - parent_contexts_a.name = 'parent_context_1' + // + // h) to filter Artifacts on Events + // - events_0.execution_id = 1 + // - events_0.type = INPUT + // - events_0.milliseconds_since_epoch = 1 + // to filter Executions on Events + // - events_0.artifact_id = 1 + // - events_0.type IN (INPUT, INTERNAL_INPUT) + // - events_0.milliseconds_since_epoch = 1 + // + // TODO(b/145945460) Support filtering on event step fields. + FilterQuery *string `protobuf:"bytes,4,opt,name=filter_query,json=filterQuery" json:"filter_query,omitempty"` +} + +// Default values for ListOperationOptions fields. +const ( + Default_ListOperationOptions_MaxResultSize = int32(20) +) + +func (x *ListOperationOptions) Reset() { + *x = ListOperationOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListOperationOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOperationOptions) ProtoMessage() {} + +func (x *ListOperationOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListOperationOptions.ProtoReflect.Descriptor instead. +func (*ListOperationOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{31} +} + +func (x *ListOperationOptions) GetMaxResultSize() int32 { + if x != nil && x.MaxResultSize != nil { + return *x.MaxResultSize + } + return Default_ListOperationOptions_MaxResultSize +} + +func (x *ListOperationOptions) GetOrderByField() *ListOperationOptions_OrderByField { + if x != nil { + return x.OrderByField + } + return nil +} + +func (x *ListOperationOptions) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +func (x *ListOperationOptions) GetFilterQuery() string { + if x != nil && x.FilterQuery != nil { + return *x.FilterQuery + } + return "" +} + +// Encapsulates information to identify the next page of resources in +// ListOperation. +type ListOperationNextPageToken struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Id offset within the resultset to start next page. + // Id offset is returned as Id is the unique field used to break ties for + // fields that might have duplicate entries, e.g. there could be two + // resources with same create_time. In such cases to break the tie in + // ordering, id offset is used. + // This field is currently only set whe order_by field is CREATE_TIME. + IdOffset *int64 `protobuf:"varint,1,opt,name=id_offset,json=idOffset" json:"id_offset,omitempty"` + // Offset value of the order by field. If ID is used this value is same as + // id_offset. + FieldOffset *int64 `protobuf:"varint,2,opt,name=field_offset,json=fieldOffset" json:"field_offset,omitempty"` + // Options set in the first call to ListOperation. This ensures that if + // next_page_token is set by the caller then ListPipelineJobs API will always + // use options set in the first call. + SetOptions *ListOperationOptions `protobuf:"bytes,3,opt,name=set_options,json=setOptions" json:"set_options,omitempty"` + // List of ids that have the same order_by field values. This is used to + // ensure List Operation does not return duplicate entries for nodes that have + // the same order_by field value. + // This field is currently only set whe order_by field is LAST_UPDATE_TIME. + ListedIds []int64 `protobuf:"varint,4,rep,name=listed_ids,json=listedIds" json:"listed_ids,omitempty"` +} + +func (x *ListOperationNextPageToken) Reset() { + *x = ListOperationNextPageToken{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListOperationNextPageToken) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOperationNextPageToken) ProtoMessage() {} + +func (x *ListOperationNextPageToken) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListOperationNextPageToken.ProtoReflect.Descriptor instead. +func (*ListOperationNextPageToken) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{32} +} + +func (x *ListOperationNextPageToken) GetIdOffset() int64 { + if x != nil && x.IdOffset != nil { + return *x.IdOffset + } + return 0 +} + +func (x *ListOperationNextPageToken) GetFieldOffset() int64 { + if x != nil && x.FieldOffset != nil { + return *x.FieldOffset + } + return 0 +} + +func (x *ListOperationNextPageToken) GetSetOptions() *ListOperationOptions { + if x != nil { + return x.SetOptions + } + return nil +} + +func (x *ListOperationNextPageToken) GetListedIds() []int64 { + if x != nil { + return x.ListedIds + } + return nil +} + +// Options for transactions. +// Note: This is under development. Clients should not use it. +type TransactionOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + extensionFields protoimpl.ExtensionFields + + // Transaction tag for debug use only. + Tag *string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"` +} + +func (x *TransactionOptions) Reset() { + *x = TransactionOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TransactionOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TransactionOptions) ProtoMessage() {} + +func (x *TransactionOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TransactionOptions.ProtoReflect.Descriptor instead. +func (*TransactionOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{33} +} + +func (x *TransactionOptions) GetTag() string { + if x != nil && x.Tag != nil { + return *x.Tag + } + return "" +} + +// TODO(b/283852485): Deprecate GetLineageGraph API after migration to +// GetLineageSubgraph API. +// The query options for `get_lineage_graph` operation. +// `query_nodes` is a list of nodes of interest. +// Currently only artifacts are supported as `query_nodes`. +// `stop_conditions` defines the filtering rules when querying a lineage graph. +// `max_node_size` defines the total number of artifacts and executions returned +// in the subgraph. +type LineageGraphQueryOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A query to specify the nodes of interest. + // `ListOperationOptions.max_result_size` sets the maximum number of nodes to + // begin with the graph search. + // TODO(b/178491112) Support query_nodes for Executions. + // + // Types that are assignable to QueryNodes: + // + // *LineageGraphQueryOptions_ArtifactsOptions + QueryNodes isLineageGraphQueryOptions_QueryNodes `protobuf_oneof:"query_nodes"` + // A constraint option to define the filtering rules when querying a lineage + // graph. + StopConditions *LineageGraphQueryOptions_BoundaryConstraint `protobuf:"bytes,2,opt,name=stop_conditions,json=stopConditions" json:"stop_conditions,omitempty"` + // Maximum total number of artifacts and executions in the whole returned + // lineage graph. + // If set to 0 or below, all related nodes will be returned without any + // number limitation. + // The number counts toward Artifacts and Executions. Nothing else considered. + // + // NOTE: There is no pagination supported. + MaxNodeSize *int64 `protobuf:"varint,3,opt,name=max_node_size,json=maxNodeSize,def=20" json:"max_node_size,omitempty"` +} + +// Default values for LineageGraphQueryOptions fields. +const ( + Default_LineageGraphQueryOptions_MaxNodeSize = int64(20) +) + +func (x *LineageGraphQueryOptions) Reset() { + *x = LineageGraphQueryOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineageGraphQueryOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineageGraphQueryOptions) ProtoMessage() {} + +func (x *LineageGraphQueryOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LineageGraphQueryOptions.ProtoReflect.Descriptor instead. +func (*LineageGraphQueryOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{34} +} + +func (m *LineageGraphQueryOptions) GetQueryNodes() isLineageGraphQueryOptions_QueryNodes { + if m != nil { + return m.QueryNodes + } + return nil +} + +func (x *LineageGraphQueryOptions) GetArtifactsOptions() *ListOperationOptions { + if x, ok := x.GetQueryNodes().(*LineageGraphQueryOptions_ArtifactsOptions); ok { + return x.ArtifactsOptions + } + return nil +} + +func (x *LineageGraphQueryOptions) GetStopConditions() *LineageGraphQueryOptions_BoundaryConstraint { + if x != nil { + return x.StopConditions + } + return nil +} + +func (x *LineageGraphQueryOptions) GetMaxNodeSize() int64 { + if x != nil && x.MaxNodeSize != nil { + return *x.MaxNodeSize + } + return Default_LineageGraphQueryOptions_MaxNodeSize +} + +type isLineageGraphQueryOptions_QueryNodes interface { + isLineageGraphQueryOptions_QueryNodes() +} + +type LineageGraphQueryOptions_ArtifactsOptions struct { + ArtifactsOptions *ListOperationOptions `protobuf:"bytes,1,opt,name=artifacts_options,json=artifactsOptions,oneof"` +} + +func (*LineageGraphQueryOptions_ArtifactsOptions) isLineageGraphQueryOptions_QueryNodes() {} + +// The query options for lineage graph tracing from a list of interested nodes. +type LineageSubgraphQueryOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to StartingNodes: + // + // *LineageSubgraphQueryOptions_StartingArtifacts + // *LineageSubgraphQueryOptions_StartingExecutions + StartingNodes isLineageSubgraphQueryOptions_StartingNodes `protobuf_oneof:"starting_nodes"` + // The maximum number of hops from the `starting_nodes` to traverse. + // A hop is defined as a jump to the next node following the path of + // node -> event -> next_node. + // For example, in the lineage graph a_1 -> e_1 -> a_2: + // a_2 is 2 hops away from a_1, and e_1 is 1 hop away from a_1. + // `max_num_hops` should be non-negative. + // When its value is set to 0, only the `starting_nodes` are returned. + MaxNumHops *int64 `protobuf:"varint,3,opt,name=max_num_hops,json=maxNumHops" json:"max_num_hops,omitempty"` + // The direction of lineage graph tracing, which means the direction of all + // hops in the tracing. + // + // An UPSTREAM hop means an expansion following the path of + // execution -> output_event -> artifact or + // artifact -> input_event -> execution + // A DOWNSTREAM hop means an expansion following the path of + // execution -> input_event -> artifact or + // artifact -> output_event -> execution + // + // Please refer to `Direction` for more details. + Direction *LineageSubgraphQueryOptions_Direction `protobuf:"varint,4,opt,name=direction,enum=ml_metadata.LineageSubgraphQueryOptions_Direction" json:"direction,omitempty"` +} + +func (x *LineageSubgraphQueryOptions) Reset() { + *x = LineageSubgraphQueryOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineageSubgraphQueryOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineageSubgraphQueryOptions) ProtoMessage() {} + +func (x *LineageSubgraphQueryOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LineageSubgraphQueryOptions.ProtoReflect.Descriptor instead. +func (*LineageSubgraphQueryOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{35} +} + +func (m *LineageSubgraphQueryOptions) GetStartingNodes() isLineageSubgraphQueryOptions_StartingNodes { + if m != nil { + return m.StartingNodes + } + return nil +} + +func (x *LineageSubgraphQueryOptions) GetStartingArtifacts() *LineageSubgraphQueryOptions_StartingNodes { + if x, ok := x.GetStartingNodes().(*LineageSubgraphQueryOptions_StartingArtifacts); ok { + return x.StartingArtifacts + } + return nil +} + +func (x *LineageSubgraphQueryOptions) GetStartingExecutions() *LineageSubgraphQueryOptions_StartingNodes { + if x, ok := x.GetStartingNodes().(*LineageSubgraphQueryOptions_StartingExecutions); ok { + return x.StartingExecutions + } + return nil +} + +func (x *LineageSubgraphQueryOptions) GetMaxNumHops() int64 { + if x != nil && x.MaxNumHops != nil { + return *x.MaxNumHops + } + return 0 +} + +func (x *LineageSubgraphQueryOptions) GetDirection() LineageSubgraphQueryOptions_Direction { + if x != nil && x.Direction != nil { + return *x.Direction + } + return LineageSubgraphQueryOptions_DIRECTION_UNSPECIFIED +} + +type isLineageSubgraphQueryOptions_StartingNodes interface { + isLineageSubgraphQueryOptions_StartingNodes() +} + +type LineageSubgraphQueryOptions_StartingArtifacts struct { + StartingArtifacts *LineageSubgraphQueryOptions_StartingNodes `protobuf:"bytes,1,opt,name=starting_artifacts,json=startingArtifacts,oneof"` +} + +type LineageSubgraphQueryOptions_StartingExecutions struct { + StartingExecutions *LineageSubgraphQueryOptions_StartingNodes `protobuf:"bytes,2,opt,name=starting_executions,json=startingExecutions,oneof"` +} + +func (*LineageSubgraphQueryOptions_StartingArtifacts) isLineageSubgraphQueryOptions_StartingNodes() {} + +func (*LineageSubgraphQueryOptions_StartingExecutions) isLineageSubgraphQueryOptions_StartingNodes() { +} + +// A simple path (e.g. {step{key:"foo"}}) can name an artifact in the context +// of an execution. +type Event_Path struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A simple path (e.g. {step{key:"foo"}}) can name an artifact in the + // context of an execution. + Steps []*Event_Path_Step `protobuf:"bytes,1,rep,name=steps" json:"steps,omitempty"` +} + +func (x *Event_Path) Reset() { + *x = Event_Path{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Event_Path) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event_Path) ProtoMessage() {} + +func (x *Event_Path) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Event_Path.ProtoReflect.Descriptor instead. +func (*Event_Path) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *Event_Path) GetSteps() []*Event_Path_Step { + if x != nil { + return x.Steps + } + return nil +} + +type Event_Path_Step struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Value: + // + // *Event_Path_Step_Index + // *Event_Path_Step_Key + Value isEvent_Path_Step_Value `protobuf_oneof:"value"` +} + +func (x *Event_Path_Step) Reset() { + *x = Event_Path_Step{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Event_Path_Step) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Event_Path_Step) ProtoMessage() {} + +func (x *Event_Path_Step) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Event_Path_Step.ProtoReflect.Descriptor instead. +func (*Event_Path_Step) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{4, 0, 0} +} + +func (m *Event_Path_Step) GetValue() isEvent_Path_Step_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *Event_Path_Step) GetIndex() int64 { + if x, ok := x.GetValue().(*Event_Path_Step_Index); ok { + return x.Index + } + return 0 +} + +func (x *Event_Path_Step) GetKey() string { + if x, ok := x.GetValue().(*Event_Path_Step_Key); ok { + return x.Key + } + return "" +} + +type isEvent_Path_Step_Value interface { + isEvent_Path_Step_Value() +} + +type Event_Path_Step_Index struct { + Index int64 `protobuf:"varint,1,opt,name=index,oneof"` +} + +type Event_Path_Step_Key struct { + Key string `protobuf:"bytes,2,opt,name=key,oneof"` +} + +func (*Event_Path_Step_Index) isEvent_Path_Step_Value() {} + +func (*Event_Path_Step_Key) isEvent_Path_Step_Value() {} + +// The options to establish encrypted connections to MySQL using SSL. +type MySQLDatabaseConfig_SSLOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The path name of the client private key file. + Key *string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` + // The path name of the client public key certificate file. + Cert *string `protobuf:"bytes,2,opt,name=cert" json:"cert,omitempty"` + // The path name of the CA certificate file. + Ca *string `protobuf:"bytes,3,opt,name=ca" json:"ca,omitempty"` + // The path name of the directory that contains trusted SSL CA certificates. + Capath *string `protobuf:"bytes,4,opt,name=capath" json:"capath,omitempty"` + // The list of permissible ciphers for SSL encryption. + Cipher *string `protobuf:"bytes,5,opt,name=cipher" json:"cipher,omitempty"` + // If set, enable verification of the server certificate against the host + // name used when connecting to the server. + VerifyServerCert *bool `protobuf:"varint,6,opt,name=verify_server_cert,json=verifyServerCert" json:"verify_server_cert,omitempty"` +} + +func (x *MySQLDatabaseConfig_SSLOptions) Reset() { + *x = MySQLDatabaseConfig_SSLOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MySQLDatabaseConfig_SSLOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MySQLDatabaseConfig_SSLOptions) ProtoMessage() {} + +func (x *MySQLDatabaseConfig_SSLOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MySQLDatabaseConfig_SSLOptions.ProtoReflect.Descriptor instead. +func (*MySQLDatabaseConfig_SSLOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{22, 0} +} + +func (x *MySQLDatabaseConfig_SSLOptions) GetKey() string { + if x != nil && x.Key != nil { + return *x.Key + } + return "" +} + +func (x *MySQLDatabaseConfig_SSLOptions) GetCert() string { + if x != nil && x.Cert != nil { + return *x.Cert + } + return "" +} + +func (x *MySQLDatabaseConfig_SSLOptions) GetCa() string { + if x != nil && x.Ca != nil { + return *x.Ca + } + return "" +} + +func (x *MySQLDatabaseConfig_SSLOptions) GetCapath() string { + if x != nil && x.Capath != nil { + return *x.Capath + } + return "" +} + +func (x *MySQLDatabaseConfig_SSLOptions) GetCipher() string { + if x != nil && x.Cipher != nil { + return *x.Cipher + } + return "" +} + +func (x *MySQLDatabaseConfig_SSLOptions) GetVerifyServerCert() bool { + if x != nil && x.VerifyServerCert != nil { + return *x.VerifyServerCert + } + return false +} + +type PostgreSQLDatabaseConfig_SSLOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // disable, allow, verify-ca, verify-full, etc. Reference: + // https://www.postgresql.org/docs/current/libpq-connect.html + Sslmode *string `protobuf:"bytes,1,opt,name=sslmode" json:"sslmode,omitempty"` + // This parameter specifies the file name of the client SSL certificate, + // replacing the default ~/.postgresql/postgresql.crt. This parameter is + // ignored if an SSL connection is not made. + Sslcert *string `protobuf:"bytes,2,opt,name=sslcert" json:"sslcert,omitempty"` + // This parameter specifies the location for the secret key used for the + // client certificate. It can either specify a file name that will be used + // instead of the default ~/.postgresql/postgresql.key, this parameter is + // ignored if an SSL connection is not made. + Sslkey *string `protobuf:"bytes,3,opt,name=sslkey" json:"sslkey,omitempty"` + // This parameter specifies the password for the secret key specified in + // sslkey, allowing client certificate private keys to be stored in + // encrypted form on disk even when interactive passphrase input is not + // practical. + Sslpassword *string `protobuf:"bytes,4,opt,name=sslpassword" json:"sslpassword,omitempty"` + // This parameter specifies the name of a file containing SSL certificate + // authority (CA) certificate(s). If the file exists, the server's + // certificate will be verified to be signed by one of these authorities. + // The default is ~/.postgresql/root.crt. + Sslrootcert *string `protobuf:"bytes,5,opt,name=sslrootcert" json:"sslrootcert,omitempty"` +} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) Reset() { + *x = PostgreSQLDatabaseConfig_SSLOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PostgreSQLDatabaseConfig_SSLOptions) ProtoMessage() {} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[49] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PostgreSQLDatabaseConfig_SSLOptions.ProtoReflect.Descriptor instead. +func (*PostgreSQLDatabaseConfig_SSLOptions) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{24, 0} +} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) GetSslmode() string { + if x != nil && x.Sslmode != nil { + return *x.Sslmode + } + return "" +} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) GetSslcert() string { + if x != nil && x.Sslcert != nil { + return *x.Sslcert + } + return "" +} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) GetSslkey() string { + if x != nil && x.Sslkey != nil { + return *x.Sslkey + } + return "" +} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) GetSslpassword() string { + if x != nil && x.Sslpassword != nil { + return *x.Sslpassword + } + return "" +} + +func (x *PostgreSQLDatabaseConfig_SSLOptions) GetSslrootcert() string { + if x != nil && x.Sslrootcert != nil { + return *x.Sslrootcert + } + return "" +} + +type MetadataStoreClientConfig_SSLConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The PEM-encoded private key as a byte string, or Empty if no private key + // should be used. + ClientKey *string `protobuf:"bytes,1,opt,name=client_key,json=clientKey" json:"client_key,omitempty"` + // The PEM-encoded certificate chain as a byte string to use or or Empty if + // no certificate chain should be used. + ServerCert *string `protobuf:"bytes,2,opt,name=server_cert,json=serverCert" json:"server_cert,omitempty"` + // The PEM-encoded root certificates as a byte string, or Empty to retrieve + // them from a default location chosen by gRPC runtime. + CustomCa *string `protobuf:"bytes,3,opt,name=custom_ca,json=customCa" json:"custom_ca,omitempty"` +} + +func (x *MetadataStoreClientConfig_SSLConfig) Reset() { + *x = MetadataStoreClientConfig_SSLConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MetadataStoreClientConfig_SSLConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataStoreClientConfig_SSLConfig) ProtoMessage() {} + +func (x *MetadataStoreClientConfig_SSLConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[50] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataStoreClientConfig_SSLConfig.ProtoReflect.Descriptor instead. +func (*MetadataStoreClientConfig_SSLConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{29, 0} +} + +func (x *MetadataStoreClientConfig_SSLConfig) GetClientKey() string { + if x != nil && x.ClientKey != nil { + return *x.ClientKey + } + return "" +} + +func (x *MetadataStoreClientConfig_SSLConfig) GetServerCert() string { + if x != nil && x.ServerCert != nil { + return *x.ServerCert + } + return "" +} + +func (x *MetadataStoreClientConfig_SSLConfig) GetCustomCa() string { + if x != nil && x.CustomCa != nil { + return *x.CustomCa + } + return "" +} + +type MetadataStoreServerConfig_SSLConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Private server key for SSL + ServerKey *string `protobuf:"bytes,1,opt,name=server_key,json=serverKey" json:"server_key,omitempty"` + // Public server certificate + ServerCert *string `protobuf:"bytes,2,opt,name=server_cert,json=serverCert" json:"server_cert,omitempty"` + // Custom certificate authority + CustomCa *string `protobuf:"bytes,3,opt,name=custom_ca,json=customCa" json:"custom_ca,omitempty"` + // Valid client certificate required? + ClientVerify *bool `protobuf:"varint,4,opt,name=client_verify,json=clientVerify" json:"client_verify,omitempty"` +} + +func (x *MetadataStoreServerConfig_SSLConfig) Reset() { + *x = MetadataStoreServerConfig_SSLConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MetadataStoreServerConfig_SSLConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataStoreServerConfig_SSLConfig) ProtoMessage() {} + +func (x *MetadataStoreServerConfig_SSLConfig) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[51] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataStoreServerConfig_SSLConfig.ProtoReflect.Descriptor instead. +func (*MetadataStoreServerConfig_SSLConfig) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{30, 0} +} + +func (x *MetadataStoreServerConfig_SSLConfig) GetServerKey() string { + if x != nil && x.ServerKey != nil { + return *x.ServerKey + } + return "" +} + +func (x *MetadataStoreServerConfig_SSLConfig) GetServerCert() string { + if x != nil && x.ServerCert != nil { + return *x.ServerCert + } + return "" +} + +func (x *MetadataStoreServerConfig_SSLConfig) GetCustomCa() string { + if x != nil && x.CustomCa != nil { + return *x.CustomCa + } + return "" +} + +func (x *MetadataStoreServerConfig_SSLConfig) GetClientVerify() bool { + if x != nil && x.ClientVerify != nil { + return *x.ClientVerify + } + return false +} + +type ListOperationOptions_OrderByField struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Field to order. + Field *ListOperationOptions_OrderByField_Field `protobuf:"varint,1,opt,name=field,enum=ml_metadata.ListOperationOptions_OrderByField_Field,def=3" json:"field,omitempty"` + // Direction of ordering. + IsAsc *bool `protobuf:"varint,2,opt,name=is_asc,json=isAsc,def=1" json:"is_asc,omitempty"` +} + +// Default values for ListOperationOptions_OrderByField fields. +const ( + Default_ListOperationOptions_OrderByField_Field = ListOperationOptions_OrderByField_ID + Default_ListOperationOptions_OrderByField_IsAsc = bool(true) +) + +func (x *ListOperationOptions_OrderByField) Reset() { + *x = ListOperationOptions_OrderByField{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListOperationOptions_OrderByField) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListOperationOptions_OrderByField) ProtoMessage() {} + +func (x *ListOperationOptions_OrderByField) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[52] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListOperationOptions_OrderByField.ProtoReflect.Descriptor instead. +func (*ListOperationOptions_OrderByField) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{31, 0} +} + +func (x *ListOperationOptions_OrderByField) GetField() ListOperationOptions_OrderByField_Field { + if x != nil && x.Field != nil { + return *x.Field + } + return Default_ListOperationOptions_OrderByField_Field +} + +func (x *ListOperationOptions_OrderByField) GetIsAsc() bool { + if x != nil && x.IsAsc != nil { + return *x.IsAsc + } + return Default_ListOperationOptions_OrderByField_IsAsc +} + +// Filtering conditions for retrieving the lineage graph. +type LineageGraphQueryOptions_BoundaryConstraint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The maximum number of hops from the `query_nodes` to traverse. + // A hop is defined as a jump to the next node following the path of + // node -> event -> next_node. + // For example, in the lineage graph a_1 -> e_1 -> a_2: + // a_2 is 2 hops away from a_1, and e_1 is 1 hop away from a_1. + // `max_num_hops` should be non-negative. + // When its value is set to 0, only the `query_nodes` are returned. + MaxNumHops *int64 `protobuf:"varint,1,opt,name=max_num_hops,json=maxNumHops" json:"max_num_hops,omitempty"` + // Filtering conditions for retrieving the lineage graph. + // Please refer to `ListOperationOptions.filter_query` for the syntax. + // + // If set, the `boundary_artifacts` defines which artifacts to keep in the + // returned lineage graph during the graph search. + // Artifacts that do not satisfy the `boundary_artifacts` are filtered out, + // and the subgraphs starting at them will be pruned. + // If not set, no artifacts will be filtered out. + // Taking the following lineage graph as example: + // (`a` represents an Artifact, `e` represents an Execution, each arrow + // represents a hop.) + // + // a_0 a_1 a_3 + // | \ / \ + // \/ \/ \/ \/ + // e_0 e_1 e_3 + // / \ + // \/ \/ + // a_2 a_4 a_5 + // \ / + // \/ \/ + // e_2 + // + // To query all the upstream and downstream nodes 3 hops away from a_4, + // while excluding the upstream subgraph starting at a_3, then + // `stop_conditions` can be set as: + // + // { + // max_num_hops: 3 + // boundary_artifacts: 'id != 3' + // } + // + // With the `stop_conditions`, {a_3, e_1, a_1, a_0, e_0} will be filtered + // out. + // The returned lineage graph looks like: + // + // e_3 + // / \ + // \/ \/ + // a_2 a_4 a_5 + // \ / + // \/ \/ + // e_2 + BoundaryArtifacts *string `protobuf:"bytes,2,opt,name=boundary_artifacts,json=boundaryArtifacts" json:"boundary_artifacts,omitempty"` + // If set, the `boundary_executions` defines which executions to keep in the + // returned lineage graph during the graph search. + // Executions that do not satisfy the `boundary_executions` are filtered out + // and the subgraphs starting at them will be pruned. + // If not set, no executions will be filtered out. + // In the example above, to query for all the upstream and downstream nodes + // 3 hops away from a_4, while excluding the upstream subgraph and the + // downstream subgraph starting at e_3, then `stop_conditions` can be set as + // + // { + // max_num_hops: 3 + // boundary_executions: 'id != 3' + // } + // + // With the `stop_conditions`, {e_3, a_5, a_3, e_1, a_1, a_0, e_0} will be + // filtered out. + // The returned lineage graph looks like: + // + // a_2 a_4 + // \ / + // \/ \/ + // e_2 + // + // However, for the following graph: + // + // a_0 a_1 a_3 + // | \ / \ + // \/ \/ \/ \/ + // e_0 e_1 e_3 + // \ / \ + // \/ \/ \/ + // a_2 a_4 a_5 + // \ / + // \/ \/ + // e_2 + // + // With the same `stop_conditions`, only {e_3, a_5, a_0, e_0} will be + // filtered out. + // The returned lineage graph looks like: + // + // a_1 a_3 + // \ / + // \/ \/ + // e_1 + // \ + // \/ + // a_2 a_4 + // \ / + // \/ \/ + // e_2 + BoundaryExecutions *string `protobuf:"bytes,3,opt,name=boundary_executions,json=boundaryExecutions" json:"boundary_executions,omitempty"` +} + +func (x *LineageGraphQueryOptions_BoundaryConstraint) Reset() { + *x = LineageGraphQueryOptions_BoundaryConstraint{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineageGraphQueryOptions_BoundaryConstraint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineageGraphQueryOptions_BoundaryConstraint) ProtoMessage() {} + +func (x *LineageGraphQueryOptions_BoundaryConstraint) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[53] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LineageGraphQueryOptions_BoundaryConstraint.ProtoReflect.Descriptor instead. +func (*LineageGraphQueryOptions_BoundaryConstraint) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{34, 0} +} + +func (x *LineageGraphQueryOptions_BoundaryConstraint) GetMaxNumHops() int64 { + if x != nil && x.MaxNumHops != nil { + return *x.MaxNumHops + } + return 0 +} + +func (x *LineageGraphQueryOptions_BoundaryConstraint) GetBoundaryArtifacts() string { + if x != nil && x.BoundaryArtifacts != nil { + return *x.BoundaryArtifacts + } + return "" +} + +func (x *LineageGraphQueryOptions_BoundaryConstraint) GetBoundaryExecutions() string { + if x != nil && x.BoundaryExecutions != nil { + return *x.BoundaryExecutions + } + return "" +} + +// `starting_nodes` is a list of nodes of interest to start graph tracing. +// NOTE: The maximum number of starting nodes is 100 at most. +type LineageSubgraphQueryOptions_StartingNodes struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // `filter_query` is a boolean expression in SQL syntax that is used to + // specify the conditions on starting nodes. + // Please refer to ListOperationOptions.filter_query for more details. + FilterQuery *string `protobuf:"bytes,1,opt,name=filter_query,json=filterQuery" json:"filter_query,omitempty"` +} + +func (x *LineageSubgraphQueryOptions_StartingNodes) Reset() { + *x = LineageSubgraphQueryOptions_StartingNodes{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LineageSubgraphQueryOptions_StartingNodes) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LineageSubgraphQueryOptions_StartingNodes) ProtoMessage() {} + +func (x *LineageSubgraphQueryOptions_StartingNodes) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_proto_msgTypes[54] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LineageSubgraphQueryOptions_StartingNodes.ProtoReflect.Descriptor instead. +func (*LineageSubgraphQueryOptions_StartingNodes) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_proto_rawDescGZIP(), []int{35, 0} +} + +func (x *LineageSubgraphQueryOptions_StartingNodes) GetFilterQuery() string { + if x != nil && x.FilterQuery != nil { + return *x.FilterQuery + } + return "" +} + +var file_ml_metadata_proto_metadata_store_proto_extTypes = []protoimpl.ExtensionInfo{ + { + ExtendedType: (*descriptorpb.EnumValueOptions)(nil), + ExtensionType: (*SystemTypeExtension)(nil), + Field: 384560917, + Name: "ml_metadata.system_type_extension", + Tag: "bytes,384560917,opt,name=system_type_extension", + Filename: "ml_metadata/proto/metadata_store.proto", + }, +} + +// Extension fields to descriptorpb.EnumValueOptions. +var ( + // The system type information of each simple type enum refers to. + // + // optional ml_metadata.SystemTypeExtension system_type_extension = 384560917; + E_SystemTypeExtension = &file_ml_metadata_proto_metadata_store_proto_extTypes[0] +) + +var File_ml_metadata_proto_metadata_store_proto protoreflect.FileDescriptor + +var file_ml_metadata_proto_metadata_store_proto_rawDesc = []byte{ + 0x0a, 0x26, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x32, 0x0a, 0x13, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x45, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x91, 0x02, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, + 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, + 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x73, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x37, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, + 0x48, 0x00, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, + 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x08, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, + 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xb5, 0x06, 0x0a, 0x08, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x79, 0x70, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x79, 0x70, 0x65, + 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, + 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x45, 0x0a, 0x0a, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x12, 0x58, 0x0a, 0x11, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x05, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x35, 0x0a, + 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x6e, + 0x63, 0x65, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x45, + 0x70, 0x6f, 0x63, 0x68, 0x12, 0x3e, 0x0a, 0x1c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x6c, 0x61, 0x73, 0x74, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x45, + 0x70, 0x6f, 0x63, 0x68, 0x12, 0x3d, 0x0a, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x41, 0x6e, 0x79, 0x52, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x1a, 0x51, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, 0x15, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x6f, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, + 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x49, 0x56, 0x45, 0x10, 0x02, 0x12, 0x17, 0x0a, 0x13, + 0x4d, 0x41, 0x52, 0x4b, 0x45, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, + 0x49, 0x4f, 0x4e, 0x10, 0x03, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, + 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x41, 0x42, 0x41, 0x4e, 0x44, 0x4f, 0x4e, 0x45, 0x44, 0x10, + 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x06, + 0x22, 0xd2, 0x04, 0x0a, 0x0c, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x49, 0x64, 0x12, 0x49, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x4c, 0x0a, + 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x2f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x53, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, 0x58, 0x0a, 0x0f, 0x50, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcd, 0x01, 0x0a, 0x15, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x44, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x26, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x1a, 0x1b, 0xaa, 0xf1, 0xfd, 0xba, + 0x0b, 0x15, 0x0a, 0x13, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x07, 0x44, 0x41, 0x54, 0x41, 0x53, + 0x45, 0x54, 0x10, 0x01, 0x1a, 0x14, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x0e, 0x0a, 0x0c, 0x6d, 0x6c, + 0x6d, 0x64, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x05, 0x4d, 0x4f, + 0x44, 0x45, 0x4c, 0x10, 0x02, 0x1a, 0x12, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x0c, 0x0a, 0x0a, 0x6d, + 0x6c, 0x6d, 0x64, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x21, 0x0a, 0x07, 0x4d, 0x45, 0x54, + 0x52, 0x49, 0x43, 0x53, 0x10, 0x03, 0x1a, 0x14, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x0e, 0x0a, 0x0c, + 0x6d, 0x6c, 0x6d, 0x64, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x27, 0x0a, 0x0a, + 0x53, 0x54, 0x41, 0x54, 0x49, 0x53, 0x54, 0x49, 0x43, 0x53, 0x10, 0x04, 0x1a, 0x17, 0xaa, 0xf1, + 0xfd, 0xba, 0x0b, 0x11, 0x0a, 0x0f, 0x6d, 0x6c, 0x6d, 0x64, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x73, 0x22, 0xaa, 0x04, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, + 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, + 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x2b, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, + 0x12, 0x2b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x38, 0x0a, + 0x18, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x5f, 0x73, 0x69, + 0x6e, 0x63, 0x65, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x16, 0x6d, 0x69, 0x6c, 0x6c, 0x69, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x53, 0x69, 0x6e, + 0x63, 0x65, 0x45, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x3d, 0x0a, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, + 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x77, 0x0a, 0x04, 0x50, 0x61, 0x74, 0x68, 0x12, 0x32, + 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x2e, 0x53, 0x74, 0x65, 0x70, 0x52, 0x05, 0x73, 0x74, 0x65, + 0x70, 0x73, 0x1a, 0x3b, 0x0a, 0x04, 0x53, 0x74, 0x65, 0x70, 0x12, 0x16, 0x0a, 0x05, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x12, 0x12, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, + 0x00, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x90, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x43, 0x4c, 0x41, 0x52, 0x45, + 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x44, 0x45, + 0x43, 0x4c, 0x41, 0x52, 0x45, 0x44, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x10, 0x02, 0x12, 0x09, + 0x0a, 0x05, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x55, 0x54, + 0x50, 0x55, 0x54, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x49, 0x4e, 0x54, 0x45, 0x52, 0x4e, 0x41, + 0x4c, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x4e, 0x54, + 0x45, 0x52, 0x4e, 0x41, 0x4c, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, 0x10, 0x06, 0x12, 0x12, + 0x0a, 0x0e, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x55, 0x54, 0x50, 0x55, 0x54, + 0x10, 0x07, 0x22, 0xaa, 0x06, 0x0a, 0x09, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x49, 0x64, 0x12, 0x46, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, + 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x46, 0x0a, 0x0a, 0x70, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x12, 0x59, 0x0a, 0x11, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x70, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x63, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x35, 0x0a, + 0x17, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x6e, + 0x63, 0x65, 0x5f, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x45, + 0x70, 0x6f, 0x63, 0x68, 0x12, 0x3e, 0x0a, 0x1c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x6c, 0x61, 0x73, 0x74, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x45, + 0x70, 0x6f, 0x63, 0x68, 0x12, 0x3d, 0x0a, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x41, 0x6e, 0x79, 0x52, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x1a, 0x51, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, 0x15, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x5e, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x4e, 0x45, 0x57, 0x10, 0x01, 0x12, 0x0b, + 0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x43, + 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, + 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x41, 0x43, 0x48, 0x45, 0x44, 0x10, + 0x05, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x06, 0x22, + 0xf9, 0x05, 0x0a, 0x0d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x49, 0x64, 0x12, 0x4a, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, + 0x70, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x3e, + 0x0a, 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x09, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x40, + 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x4d, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x30, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x2e, + 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x73, + 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x1a, + 0x58, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xef, 0x01, 0x0a, 0x15, 0x53, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x42, 0x61, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, 0x00, 0x1a, 0x1c, + 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x16, 0x0a, 0x14, 0x75, 0x6e, 0x73, 0x65, 0x74, 0x5f, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x05, + 0x54, 0x52, 0x41, 0x49, 0x4e, 0x10, 0x01, 0x1a, 0x12, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x0c, 0x0a, + 0x0a, 0x6d, 0x6c, 0x6d, 0x64, 0x2e, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x12, 0x25, 0x0a, 0x09, 0x54, + 0x52, 0x41, 0x4e, 0x53, 0x46, 0x4f, 0x52, 0x4d, 0x10, 0x02, 0x1a, 0x16, 0xaa, 0xf1, 0xfd, 0xba, + 0x0b, 0x10, 0x0a, 0x0e, 0x6d, 0x6c, 0x6d, 0x64, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, + 0x72, 0x6d, 0x12, 0x21, 0x0a, 0x07, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x10, 0x03, 0x1a, + 0x14, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x0e, 0x0a, 0x0c, 0x6d, 0x6c, 0x6d, 0x64, 0x2e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x23, 0x0a, 0x08, 0x45, 0x56, 0x41, 0x4c, 0x55, 0x41, 0x54, + 0x45, 0x10, 0x04, 0x1a, 0x15, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x0f, 0x0a, 0x0d, 0x6d, 0x6c, 0x6d, + 0x64, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x44, 0x45, + 0x50, 0x4c, 0x4f, 0x59, 0x10, 0x05, 0x1a, 0x13, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x0d, 0x0a, 0x0b, + 0x6d, 0x6c, 0x6d, 0x64, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x22, 0xbf, 0x03, 0x0a, 0x0b, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, + 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x48, 0x0a, 0x0a, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x28, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x4b, 0x0a, 0x09, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x65, + 0x64, 0x42, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x08, 0x62, 0x61, 0x73, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x1a, 0x58, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x3e, 0x0a, + 0x15, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x42, 0x61, + 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x0a, 0x05, 0x55, 0x4e, 0x53, 0x45, 0x54, 0x10, + 0x00, 0x1a, 0x1a, 0xaa, 0xf1, 0xfd, 0xba, 0x0b, 0x14, 0x0a, 0x12, 0x75, 0x6e, 0x73, 0x65, 0x74, + 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0xfc, 0x04, + 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, + 0x07, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, + 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x44, 0x0a, 0x0a, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x12, 0x57, 0x0a, 0x11, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x70, 0x72, 0x6f, 0x70, + 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x2e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, + 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x10, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x17, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, + 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x14, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x45, 0x70, 0x6f, 0x63, + 0x68, 0x12, 0x3e, 0x0a, 0x1c, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x5f, 0x65, 0x70, 0x6f, 0x63, + 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x18, 0x6c, 0x61, 0x73, 0x74, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x53, 0x69, 0x6e, 0x63, 0x65, 0x45, 0x70, 0x6f, 0x63, + 0x68, 0x12, 0x3d, 0x0a, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, + 0x52, 0x0e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x1a, 0x51, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x1a, 0x57, 0x0a, 0x15, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50, 0x72, 0x6f, + 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4d, 0x0a, 0x0b, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x0b, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x22, 0x4f, 0x0a, 0x0b, 0x41, + 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x22, 0x47, 0x0a, 0x0d, + 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x07, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x08, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x9b, 0x04, 0x0a, 0x0c, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, + 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x40, 0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x3d, 0x0a, + 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x09, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x12, 0x36, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x2a, 0x0a, 0x06, 0x65, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3c, 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x92, 0x04, 0x0a, 0x12, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x33, 0x0a, 0x06, 0x73, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x06, 0x73, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x12, + 0x45, 0x0a, 0x0a, 0x75, 0x6e, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x55, 0x6e, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x09, 0x75, 0x6e, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x51, 0x0a, 0x0c, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x73, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x39, 0x0a, 0x04, 0x6c, 0x69, 0x73, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, + 0x6c, 0x69, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4e, 0x6f, 0x6e, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x12, + 0x36, 0x0a, 0x03, 0x61, 0x6e, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x6e, 0x79, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x48, 0x00, 0x52, 0x03, 0x61, 0x6e, 0x79, 0x12, 0x3c, 0x0a, 0x05, 0x74, 0x75, 0x70, 0x6c, 0x65, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x05, + 0x74, 0x75, 0x70, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x04, 0x64, 0x69, 0x63, 0x74, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x44, 0x69, 0x63, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x48, 0x00, 0x52, 0x04, 0x64, 0x69, 0x63, 0x74, + 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x22, 0x5a, 0x0a, 0x17, 0x55, 0x6e, 0x69, 0x6f, + 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x3f, 0x0a, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0a, 0x63, 0x61, 0x6e, 0x64, 0x69, 0x64, + 0x61, 0x74, 0x65, 0x73, 0x22, 0x63, 0x0a, 0x1e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, + 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x41, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x72, + 0x61, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x73, 0x22, 0x53, 0x0a, 0x16, 0x4c, 0x69, 0x73, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x39, 0x0a, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x18, + 0x0a, 0x16, 0x4e, 0x6f, 0x6e, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x17, 0x0a, 0x15, 0x41, 0x6e, 0x79, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x56, 0x0a, 0x17, 0x54, 0x75, 0x70, 0x6c, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3b, 0x0a, 0x08, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xd7, 0x02, 0x0a, 0x16, 0x44, 0x69, + 0x63, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x53, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x69, 0x63, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x2e, 0x50, 0x72, + 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, + 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x33, 0x0a, 0x16, 0x6e, 0x6f, 0x6e, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x6f, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x69, + 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x6e, 0x6f, 0x6e, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x4e, 0x6f, 0x74, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x53, + 0x0a, 0x15, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x13, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x1a, 0x5e, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x35, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x14, 0x0a, 0x12, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0xbc, 0x03, 0x0a, 0x13, 0x4d, 0x79, + 0x53, 0x51, 0x4c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, + 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x4c, 0x0a, + 0x0b, 0x73, 0x73, 0x6c, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x53, 0x4c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x0a, 0x73, 0x73, 0x6c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x73, + 0x6b, 0x69, 0x70, 0x5f, 0x64, 0x62, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, 0x44, 0x62, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xa0, 0x01, 0x0a, 0x0a, 0x53, 0x53, 0x4c, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x65, 0x72, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x65, 0x72, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x63, 0x61, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x63, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, + 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x70, 0x61, + 0x74, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x63, 0x69, 0x70, 0x68, 0x65, 0x72, 0x12, 0x2c, 0x0a, 0x12, 0x76, 0x65, + 0x72, 0x69, 0x66, 0x79, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x10, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x22, 0xf6, 0x01, 0x0a, 0x1a, 0x53, 0x71, 0x6c, + 0x69, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x6c, 0x65, 0x6e, + 0x61, 0x6d, 0x65, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, + 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x55, 0x72, 0x69, 0x12, 0x5f, 0x0a, 0x0f, 0x63, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x36, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x53, 0x71, 0x6c, 0x69, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x54, 0x0a, 0x0e, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x0b, 0x0a, + 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, + 0x41, 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x45, 0x41, 0x44, + 0x57, 0x52, 0x49, 0x54, 0x45, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x45, 0x41, 0x44, 0x57, + 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f, 0x50, 0x45, 0x4e, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x10, + 0x03, 0x22, 0xdb, 0x03, 0x0a, 0x18, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, + 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x61, 0x64, 0x64, 0x72, 0x12, 0x12, + 0x0a, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x6f, + 0x72, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, + 0x72, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x64, 0x62, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x64, 0x62, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x6b, 0x69, 0x70, 0x5f, 0x64, + 0x62, 0x5f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0e, 0x73, 0x6b, 0x69, 0x70, 0x44, 0x62, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x4e, 0x0a, 0x09, 0x73, 0x73, 0x6c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x53, 0x4c, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x09, 0x73, 0x73, 0x6c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x1a, 0x9c, 0x01, 0x0a, 0x0a, 0x53, 0x53, 0x4c, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x73, 0x6c, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x73, 0x6c, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x73, 0x6c, + 0x63, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x73, 0x6c, 0x63, + 0x65, 0x72, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x73, 0x6c, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x73, 0x6c, 0x6b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x73, + 0x73, 0x6c, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x73, 0x73, 0x6c, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x20, 0x0a, + 0x0b, 0x73, 0x73, 0x6c, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x65, 0x72, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x73, 0x73, 0x6c, 0x72, 0x6f, 0x6f, 0x74, 0x63, 0x65, 0x72, 0x74, 0x22, + 0x95, 0x01, 0x0a, 0x10, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x38, 0x0a, 0x18, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x75, + 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x5f, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x16, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x55, 0x70, + 0x67, 0x72, 0x61, 0x64, 0x65, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x41, + 0x0a, 0x1b, 0x64, 0x6f, 0x77, 0x6e, 0x67, 0x72, 0x61, 0x64, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x03, 0x3a, 0x02, 0x2d, 0x31, 0x52, 0x18, 0x64, 0x6f, 0x77, 0x6e, 0x67, 0x72, 0x61, + 0x64, 0x65, 0x54, 0x6f, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x36, 0x0a, 0x0c, 0x52, 0x65, 0x74, 0x72, 0x79, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x6e, + 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x4e, 0x75, 0x6d, 0x52, 0x65, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, + 0xea, 0x02, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x46, 0x0a, 0x0d, 0x66, 0x61, 0x6b, 0x65, 0x5f, 0x64, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x46, 0x61, 0x6b, 0x65, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0c, + 0x66, 0x61, 0x6b, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x05, + 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x79, 0x53, 0x51, 0x4c, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, + 0x05, 0x6d, 0x79, 0x73, 0x71, 0x6c, 0x12, 0x41, 0x0a, 0x06, 0x73, 0x71, 0x6c, 0x69, 0x74, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x71, 0x6c, 0x69, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, + 0x00, 0x52, 0x06, 0x73, 0x71, 0x6c, 0x69, 0x74, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x70, 0x6f, 0x73, + 0x74, 0x67, 0x72, 0x65, 0x73, 0x71, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x74, + 0x67, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, + 0x71, 0x6c, 0x12, 0x3e, 0x0a, 0x0d, 0x72, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x74, 0x72, 0x79, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0c, 0x72, 0x65, 0x74, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x42, 0x08, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x88, 0x01, 0x0a, + 0x14, 0x47, 0x72, 0x70, 0x63, 0x43, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x72, 0x67, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x3b, 0x0a, 0x1a, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, 0x63, + 0x65, 0x69, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x65, 0x6e, + 0x67, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x17, 0x6d, 0x61, 0x78, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4c, 0x65, 0x6e, 0x67, + 0x74, 0x68, 0x12, 0x33, 0x0a, 0x16, 0x68, 0x74, 0x74, 0x70, 0x32, 0x5f, 0x6d, 0x61, 0x78, 0x5f, + 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x13, 0x68, 0x74, 0x74, 0x70, 0x32, 0x4d, 0x61, 0x78, 0x50, 0x69, 0x6e, 0x67, + 0x53, 0x74, 0x72, 0x69, 0x6b, 0x65, 0x73, 0x22, 0xfc, 0x02, 0x0a, 0x19, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x72, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x4f, 0x0a, + 0x0a, 0x73, 0x73, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x30, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x53, 0x4c, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x52, 0x09, 0x73, 0x73, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4e, + 0x0a, 0x11, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x72, 0x70, 0x63, 0x43, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x10, 0x63, 0x68, + 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x41, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x2c, + 0x0a, 0x12, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x5f, 0x73, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x01, 0x52, 0x10, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x1a, 0x68, 0x0a, 0x09, + 0x53, 0x53, 0x4c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x75, 0x73, + 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x61, 0x22, 0x94, 0x03, 0x0a, 0x19, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4a, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x10, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x12, 0x4a, 0x0a, 0x11, 0x6d, 0x69, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, 0x69, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x10, 0x6d, 0x69, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4f, 0x0a, 0x0a, + 0x73, 0x73, 0x6c, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x30, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x53, 0x4c, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x52, 0x09, 0x73, 0x73, 0x6c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x8d, 0x01, + 0x0a, 0x09, 0x53, 0x53, 0x4c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x65, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x65, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, + 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x63, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x43, 0x61, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x22, 0xb0, 0x03, + 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x2a, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x3a, + 0x02, 0x32, 0x30, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x53, 0x69, + 0x7a, 0x65, 0x12, 0x54, 0x0a, 0x0e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x5f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x72, + 0x64, 0x65, 0x72, 0x42, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x52, 0x0c, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x42, 0x79, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, + 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x1a, 0xca, 0x01, 0x0a, 0x0c, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x12, 0x4e, 0x0a, 0x05, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x46, 0x69, + 0x65, 0x6c, 0x64, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x3a, 0x02, 0x49, 0x44, 0x52, 0x05, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x12, 0x1b, 0x0a, 0x06, 0x69, 0x73, 0x5f, 0x61, 0x73, 0x63, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x52, 0x05, 0x69, 0x73, 0x41, 0x73, + 0x63, 0x22, 0x4d, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x15, 0x0a, 0x11, 0x46, 0x49, + 0x45, 0x4c, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, + 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, + 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x4c, 0x41, 0x53, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, + 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x02, 0x12, 0x06, 0x0a, 0x02, 0x49, 0x44, 0x10, 0x03, + 0x22, 0xbf, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x4e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, + 0x1b, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x08, 0x69, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0b, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, + 0x42, 0x0a, 0x0b, 0x73, 0x65, 0x74, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0a, 0x73, 0x65, 0x74, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x03, 0x52, 0x09, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x64, 0x49, + 0x64, 0x73, 0x22, 0x31, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x2a, 0x09, 0x08, 0xe8, 0x07, 0x10, + 0x80, 0x80, 0x80, 0x80, 0x02, 0x22, 0x9f, 0x03, 0x0a, 0x18, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, + 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x11, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x5f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x48, 0x00, 0x52, 0x10, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x61, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x63, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x67, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, + 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x52, 0x0e, 0x73, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, + 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x5f, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x02, + 0x32, 0x30, 0x52, 0x0b, 0x6d, 0x61, 0x78, 0x4e, 0x6f, 0x64, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x1a, + 0x96, 0x01, 0x0a, 0x12, 0x42, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x73, + 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x20, 0x0a, 0x0c, 0x6d, 0x61, 0x78, 0x5f, 0x6e, 0x75, + 0x6d, 0x5f, 0x68, 0x6f, 0x70, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x6d, 0x61, + 0x78, 0x4e, 0x75, 0x6d, 0x48, 0x6f, 0x70, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x62, 0x6f, 0x75, 0x6e, + 0x64, 0x61, 0x72, 0x79, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x13, 0x62, 0x6f, 0x75, 0x6e, 0x64, + 0x61, 0x72, 0x79, 0x5f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x0d, 0x0a, 0x0b, 0x71, 0x75, 0x65, 0x72, + 0x79, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x22, 0x84, 0x04, 0x0a, 0x1b, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x67, 0x0a, 0x12, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x69, 0x6e, 0x67, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x48, 0x00, 0x52, 0x11, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x12, 0x69, 0x0a, 0x13, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, + 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x48, 0x00, 0x52, 0x12, 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, + 0x67, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x20, 0x0a, 0x0c, 0x6d, + 0x61, 0x78, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x68, 0x6f, 0x70, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x4e, 0x75, 0x6d, 0x48, 0x6f, 0x70, 0x73, 0x12, 0x50, 0x0a, + 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x32, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, + 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x44, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, + 0x32, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x4e, 0x6f, 0x64, 0x65, 0x73, + 0x12, 0x21, 0x0a, 0x0c, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x51, 0x75, + 0x65, 0x72, 0x79, 0x22, 0x57, 0x0a, 0x09, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x55, + 0x50, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x44, 0x4f, 0x57, + 0x4e, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x42, 0x49, 0x44, + 0x49, 0x52, 0x45, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x41, 0x4c, 0x10, 0x03, 0x42, 0x10, 0x0a, 0x0e, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x2a, 0x60, + 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, + 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x49, + 0x4e, 0x54, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, 0x02, + 0x12, 0x0a, 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, + 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x50, 0x52, 0x4f, 0x54, + 0x4f, 0x10, 0x05, 0x12, 0x0b, 0x0a, 0x07, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x06, + 0x3a, 0x7b, 0x0a, 0x15, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6e, 0x75, 0x6d, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x95, 0xde, 0xaf, + 0xb7, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, + 0x54, 0x79, 0x70, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x40, 0x5a, + 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, + 0x64, 0x61, 0x74, 0x61, 0x68, 0x75, 0x62, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, + 0x2d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, +} + +var ( + file_ml_metadata_proto_metadata_store_proto_rawDescOnce sync.Once + file_ml_metadata_proto_metadata_store_proto_rawDescData = file_ml_metadata_proto_metadata_store_proto_rawDesc +) + +func file_ml_metadata_proto_metadata_store_proto_rawDescGZIP() []byte { + file_ml_metadata_proto_metadata_store_proto_rawDescOnce.Do(func() { + file_ml_metadata_proto_metadata_store_proto_rawDescData = protoimpl.X.CompressGZIP(file_ml_metadata_proto_metadata_store_proto_rawDescData) + }) + return file_ml_metadata_proto_metadata_store_proto_rawDescData +} + +var file_ml_metadata_proto_metadata_store_proto_enumTypes = make([]protoimpl.EnumInfo, 10) +var file_ml_metadata_proto_metadata_store_proto_msgTypes = make([]protoimpl.MessageInfo, 55) +var file_ml_metadata_proto_metadata_store_proto_goTypes = []interface{}{ + (PropertyType)(0), // 0: ml_metadata.PropertyType + (Artifact_State)(0), // 1: ml_metadata.Artifact.State + (ArtifactType_SystemDefinedBaseType)(0), // 2: ml_metadata.ArtifactType.SystemDefinedBaseType + (Event_Type)(0), // 3: ml_metadata.Event.Type + (Execution_State)(0), // 4: ml_metadata.Execution.State + (ExecutionType_SystemDefinedBaseType)(0), // 5: ml_metadata.ExecutionType.SystemDefinedBaseType + (ContextType_SystemDefinedBaseType)(0), // 6: ml_metadata.ContextType.SystemDefinedBaseType + (SqliteMetadataSourceConfig_ConnectionMode)(0), // 7: ml_metadata.SqliteMetadataSourceConfig.ConnectionMode + (ListOperationOptions_OrderByField_Field)(0), // 8: ml_metadata.ListOperationOptions.OrderByField.Field + (LineageSubgraphQueryOptions_Direction)(0), // 9: ml_metadata.LineageSubgraphQueryOptions.Direction + (*SystemTypeExtension)(nil), // 10: ml_metadata.SystemTypeExtension + (*Value)(nil), // 11: ml_metadata.Value + (*Artifact)(nil), // 12: ml_metadata.Artifact + (*ArtifactType)(nil), // 13: ml_metadata.ArtifactType + (*Event)(nil), // 14: ml_metadata.Event + (*Execution)(nil), // 15: ml_metadata.Execution + (*ExecutionType)(nil), // 16: ml_metadata.ExecutionType + (*ContextType)(nil), // 17: ml_metadata.ContextType + (*Context)(nil), // 18: ml_metadata.Context + (*Attribution)(nil), // 19: ml_metadata.Attribution + (*Association)(nil), // 20: ml_metadata.Association + (*ParentContext)(nil), // 21: ml_metadata.ParentContext + (*LineageGraph)(nil), // 22: ml_metadata.LineageGraph + (*ArtifactStructType)(nil), // 23: ml_metadata.ArtifactStructType + (*UnionArtifactStructType)(nil), // 24: ml_metadata.UnionArtifactStructType + (*IntersectionArtifactStructType)(nil), // 25: ml_metadata.IntersectionArtifactStructType + (*ListArtifactStructType)(nil), // 26: ml_metadata.ListArtifactStructType + (*NoneArtifactStructType)(nil), // 27: ml_metadata.NoneArtifactStructType + (*AnyArtifactStructType)(nil), // 28: ml_metadata.AnyArtifactStructType + (*TupleArtifactStructType)(nil), // 29: ml_metadata.TupleArtifactStructType + (*DictArtifactStructType)(nil), // 30: ml_metadata.DictArtifactStructType + (*FakeDatabaseConfig)(nil), // 31: ml_metadata.FakeDatabaseConfig + (*MySQLDatabaseConfig)(nil), // 32: ml_metadata.MySQLDatabaseConfig + (*SqliteMetadataSourceConfig)(nil), // 33: ml_metadata.SqliteMetadataSourceConfig + (*PostgreSQLDatabaseConfig)(nil), // 34: ml_metadata.PostgreSQLDatabaseConfig + (*MigrationOptions)(nil), // 35: ml_metadata.MigrationOptions + (*RetryOptions)(nil), // 36: ml_metadata.RetryOptions + (*ConnectionConfig)(nil), // 37: ml_metadata.ConnectionConfig + (*GrpcChannelArguments)(nil), // 38: ml_metadata.GrpcChannelArguments + (*MetadataStoreClientConfig)(nil), // 39: ml_metadata.MetadataStoreClientConfig + (*MetadataStoreServerConfig)(nil), // 40: ml_metadata.MetadataStoreServerConfig + (*ListOperationOptions)(nil), // 41: ml_metadata.ListOperationOptions + (*ListOperationNextPageToken)(nil), // 42: ml_metadata.ListOperationNextPageToken + (*TransactionOptions)(nil), // 43: ml_metadata.TransactionOptions + (*LineageGraphQueryOptions)(nil), // 44: ml_metadata.LineageGraphQueryOptions + (*LineageSubgraphQueryOptions)(nil), // 45: ml_metadata.LineageSubgraphQueryOptions + nil, // 46: ml_metadata.Artifact.PropertiesEntry + nil, // 47: ml_metadata.Artifact.CustomPropertiesEntry + nil, // 48: ml_metadata.ArtifactType.PropertiesEntry + (*Event_Path)(nil), // 49: ml_metadata.Event.Path + (*Event_Path_Step)(nil), // 50: ml_metadata.Event.Path.Step + nil, // 51: ml_metadata.Execution.PropertiesEntry + nil, // 52: ml_metadata.Execution.CustomPropertiesEntry + nil, // 53: ml_metadata.ExecutionType.PropertiesEntry + nil, // 54: ml_metadata.ContextType.PropertiesEntry + nil, // 55: ml_metadata.Context.PropertiesEntry + nil, // 56: ml_metadata.Context.CustomPropertiesEntry + nil, // 57: ml_metadata.DictArtifactStructType.PropertiesEntry + (*MySQLDatabaseConfig_SSLOptions)(nil), // 58: ml_metadata.MySQLDatabaseConfig.SSLOptions + (*PostgreSQLDatabaseConfig_SSLOptions)(nil), // 59: ml_metadata.PostgreSQLDatabaseConfig.SSLOptions + (*MetadataStoreClientConfig_SSLConfig)(nil), // 60: ml_metadata.MetadataStoreClientConfig.SSLConfig + (*MetadataStoreServerConfig_SSLConfig)(nil), // 61: ml_metadata.MetadataStoreServerConfig.SSLConfig + (*ListOperationOptions_OrderByField)(nil), // 62: ml_metadata.ListOperationOptions.OrderByField + (*LineageGraphQueryOptions_BoundaryConstraint)(nil), // 63: ml_metadata.LineageGraphQueryOptions.BoundaryConstraint + (*LineageSubgraphQueryOptions_StartingNodes)(nil), // 64: ml_metadata.LineageSubgraphQueryOptions.StartingNodes + (*structpb.Struct)(nil), // 65: google.protobuf.Struct + (*anypb.Any)(nil), // 66: google.protobuf.Any + (*descriptorpb.EnumValueOptions)(nil), // 67: google.protobuf.EnumValueOptions +} +var file_ml_metadata_proto_metadata_store_proto_depIdxs = []int32{ + 65, // 0: ml_metadata.Value.struct_value:type_name -> google.protobuf.Struct + 66, // 1: ml_metadata.Value.proto_value:type_name -> google.protobuf.Any + 46, // 2: ml_metadata.Artifact.properties:type_name -> ml_metadata.Artifact.PropertiesEntry + 47, // 3: ml_metadata.Artifact.custom_properties:type_name -> ml_metadata.Artifact.CustomPropertiesEntry + 1, // 4: ml_metadata.Artifact.state:type_name -> ml_metadata.Artifact.State + 66, // 5: ml_metadata.Artifact.system_metadata:type_name -> google.protobuf.Any + 48, // 6: ml_metadata.ArtifactType.properties:type_name -> ml_metadata.ArtifactType.PropertiesEntry + 2, // 7: ml_metadata.ArtifactType.base_type:type_name -> ml_metadata.ArtifactType.SystemDefinedBaseType + 49, // 8: ml_metadata.Event.path:type_name -> ml_metadata.Event.Path + 3, // 9: ml_metadata.Event.type:type_name -> ml_metadata.Event.Type + 66, // 10: ml_metadata.Event.system_metadata:type_name -> google.protobuf.Any + 4, // 11: ml_metadata.Execution.last_known_state:type_name -> ml_metadata.Execution.State + 51, // 12: ml_metadata.Execution.properties:type_name -> ml_metadata.Execution.PropertiesEntry + 52, // 13: ml_metadata.Execution.custom_properties:type_name -> ml_metadata.Execution.CustomPropertiesEntry + 66, // 14: ml_metadata.Execution.system_metadata:type_name -> google.protobuf.Any + 53, // 15: ml_metadata.ExecutionType.properties:type_name -> ml_metadata.ExecutionType.PropertiesEntry + 23, // 16: ml_metadata.ExecutionType.input_type:type_name -> ml_metadata.ArtifactStructType + 23, // 17: ml_metadata.ExecutionType.output_type:type_name -> ml_metadata.ArtifactStructType + 5, // 18: ml_metadata.ExecutionType.base_type:type_name -> ml_metadata.ExecutionType.SystemDefinedBaseType + 54, // 19: ml_metadata.ContextType.properties:type_name -> ml_metadata.ContextType.PropertiesEntry + 6, // 20: ml_metadata.ContextType.base_type:type_name -> ml_metadata.ContextType.SystemDefinedBaseType + 55, // 21: ml_metadata.Context.properties:type_name -> ml_metadata.Context.PropertiesEntry + 56, // 22: ml_metadata.Context.custom_properties:type_name -> ml_metadata.Context.CustomPropertiesEntry + 66, // 23: ml_metadata.Context.system_metadata:type_name -> google.protobuf.Any + 13, // 24: ml_metadata.LineageGraph.artifact_types:type_name -> ml_metadata.ArtifactType + 16, // 25: ml_metadata.LineageGraph.execution_types:type_name -> ml_metadata.ExecutionType + 17, // 26: ml_metadata.LineageGraph.context_types:type_name -> ml_metadata.ContextType + 12, // 27: ml_metadata.LineageGraph.artifacts:type_name -> ml_metadata.Artifact + 15, // 28: ml_metadata.LineageGraph.executions:type_name -> ml_metadata.Execution + 18, // 29: ml_metadata.LineageGraph.contexts:type_name -> ml_metadata.Context + 14, // 30: ml_metadata.LineageGraph.events:type_name -> ml_metadata.Event + 19, // 31: ml_metadata.LineageGraph.attributions:type_name -> ml_metadata.Attribution + 20, // 32: ml_metadata.LineageGraph.associations:type_name -> ml_metadata.Association + 13, // 33: ml_metadata.ArtifactStructType.simple:type_name -> ml_metadata.ArtifactType + 24, // 34: ml_metadata.ArtifactStructType.union_type:type_name -> ml_metadata.UnionArtifactStructType + 25, // 35: ml_metadata.ArtifactStructType.intersection:type_name -> ml_metadata.IntersectionArtifactStructType + 26, // 36: ml_metadata.ArtifactStructType.list:type_name -> ml_metadata.ListArtifactStructType + 27, // 37: ml_metadata.ArtifactStructType.none:type_name -> ml_metadata.NoneArtifactStructType + 28, // 38: ml_metadata.ArtifactStructType.any:type_name -> ml_metadata.AnyArtifactStructType + 29, // 39: ml_metadata.ArtifactStructType.tuple:type_name -> ml_metadata.TupleArtifactStructType + 30, // 40: ml_metadata.ArtifactStructType.dict:type_name -> ml_metadata.DictArtifactStructType + 23, // 41: ml_metadata.UnionArtifactStructType.candidates:type_name -> ml_metadata.ArtifactStructType + 23, // 42: ml_metadata.IntersectionArtifactStructType.constraints:type_name -> ml_metadata.ArtifactStructType + 23, // 43: ml_metadata.ListArtifactStructType.element:type_name -> ml_metadata.ArtifactStructType + 23, // 44: ml_metadata.TupleArtifactStructType.elements:type_name -> ml_metadata.ArtifactStructType + 57, // 45: ml_metadata.DictArtifactStructType.properties:type_name -> ml_metadata.DictArtifactStructType.PropertiesEntry + 23, // 46: ml_metadata.DictArtifactStructType.extra_properties_type:type_name -> ml_metadata.ArtifactStructType + 58, // 47: ml_metadata.MySQLDatabaseConfig.ssl_options:type_name -> ml_metadata.MySQLDatabaseConfig.SSLOptions + 7, // 48: ml_metadata.SqliteMetadataSourceConfig.connection_mode:type_name -> ml_metadata.SqliteMetadataSourceConfig.ConnectionMode + 59, // 49: ml_metadata.PostgreSQLDatabaseConfig.ssloption:type_name -> ml_metadata.PostgreSQLDatabaseConfig.SSLOptions + 31, // 50: ml_metadata.ConnectionConfig.fake_database:type_name -> ml_metadata.FakeDatabaseConfig + 32, // 51: ml_metadata.ConnectionConfig.mysql:type_name -> ml_metadata.MySQLDatabaseConfig + 33, // 52: ml_metadata.ConnectionConfig.sqlite:type_name -> ml_metadata.SqliteMetadataSourceConfig + 34, // 53: ml_metadata.ConnectionConfig.postgresql:type_name -> ml_metadata.PostgreSQLDatabaseConfig + 36, // 54: ml_metadata.ConnectionConfig.retry_options:type_name -> ml_metadata.RetryOptions + 60, // 55: ml_metadata.MetadataStoreClientConfig.ssl_config:type_name -> ml_metadata.MetadataStoreClientConfig.SSLConfig + 38, // 56: ml_metadata.MetadataStoreClientConfig.channel_arguments:type_name -> ml_metadata.GrpcChannelArguments + 37, // 57: ml_metadata.MetadataStoreServerConfig.connection_config:type_name -> ml_metadata.ConnectionConfig + 35, // 58: ml_metadata.MetadataStoreServerConfig.migration_options:type_name -> ml_metadata.MigrationOptions + 61, // 59: ml_metadata.MetadataStoreServerConfig.ssl_config:type_name -> ml_metadata.MetadataStoreServerConfig.SSLConfig + 62, // 60: ml_metadata.ListOperationOptions.order_by_field:type_name -> ml_metadata.ListOperationOptions.OrderByField + 41, // 61: ml_metadata.ListOperationNextPageToken.set_options:type_name -> ml_metadata.ListOperationOptions + 41, // 62: ml_metadata.LineageGraphQueryOptions.artifacts_options:type_name -> ml_metadata.ListOperationOptions + 63, // 63: ml_metadata.LineageGraphQueryOptions.stop_conditions:type_name -> ml_metadata.LineageGraphQueryOptions.BoundaryConstraint + 64, // 64: ml_metadata.LineageSubgraphQueryOptions.starting_artifacts:type_name -> ml_metadata.LineageSubgraphQueryOptions.StartingNodes + 64, // 65: ml_metadata.LineageSubgraphQueryOptions.starting_executions:type_name -> ml_metadata.LineageSubgraphQueryOptions.StartingNodes + 9, // 66: ml_metadata.LineageSubgraphQueryOptions.direction:type_name -> ml_metadata.LineageSubgraphQueryOptions.Direction + 11, // 67: ml_metadata.Artifact.PropertiesEntry.value:type_name -> ml_metadata.Value + 11, // 68: ml_metadata.Artifact.CustomPropertiesEntry.value:type_name -> ml_metadata.Value + 0, // 69: ml_metadata.ArtifactType.PropertiesEntry.value:type_name -> ml_metadata.PropertyType + 50, // 70: ml_metadata.Event.Path.steps:type_name -> ml_metadata.Event.Path.Step + 11, // 71: ml_metadata.Execution.PropertiesEntry.value:type_name -> ml_metadata.Value + 11, // 72: ml_metadata.Execution.CustomPropertiesEntry.value:type_name -> ml_metadata.Value + 0, // 73: ml_metadata.ExecutionType.PropertiesEntry.value:type_name -> ml_metadata.PropertyType + 0, // 74: ml_metadata.ContextType.PropertiesEntry.value:type_name -> ml_metadata.PropertyType + 11, // 75: ml_metadata.Context.PropertiesEntry.value:type_name -> ml_metadata.Value + 11, // 76: ml_metadata.Context.CustomPropertiesEntry.value:type_name -> ml_metadata.Value + 23, // 77: ml_metadata.DictArtifactStructType.PropertiesEntry.value:type_name -> ml_metadata.ArtifactStructType + 8, // 78: ml_metadata.ListOperationOptions.OrderByField.field:type_name -> ml_metadata.ListOperationOptions.OrderByField.Field + 67, // 79: ml_metadata.system_type_extension:extendee -> google.protobuf.EnumValueOptions + 10, // 80: ml_metadata.system_type_extension:type_name -> ml_metadata.SystemTypeExtension + 81, // [81:81] is the sub-list for method output_type + 81, // [81:81] is the sub-list for method input_type + 80, // [80:81] is the sub-list for extension type_name + 79, // [79:80] is the sub-list for extension extendee + 0, // [0:79] is the sub-list for field type_name +} + +func init() { file_ml_metadata_proto_metadata_store_proto_init() } +func file_ml_metadata_proto_metadata_store_proto_init() { + if File_ml_metadata_proto_metadata_store_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_ml_metadata_proto_metadata_store_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SystemTypeExtension); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Artifact); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ArtifactType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Execution); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ExecutionType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ContextType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Context); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Attribution); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Association); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ParentContext); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineageGraph); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnionArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*IntersectionArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*NoneArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AnyArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TupleArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DictArtifactStructType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FakeDatabaseConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MySQLDatabaseConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SqliteMetadataSourceConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PostgreSQLDatabaseConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MigrationOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RetryOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnectionConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GrpcChannelArguments); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetadataStoreClientConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetadataStoreServerConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListOperationOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListOperationNextPageToken); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TransactionOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + case 3: + return &v.extensionFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineageGraphQueryOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineageSubgraphQueryOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event_Path); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Event_Path_Step); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MySQLDatabaseConfig_SSLOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PostgreSQLDatabaseConfig_SSLOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetadataStoreClientConfig_SSLConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetadataStoreServerConfig_SSLConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListOperationOptions_OrderByField); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineageGraphQueryOptions_BoundaryConstraint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LineageSubgraphQueryOptions_StartingNodes); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*Value_IntValue)(nil), + (*Value_DoubleValue)(nil), + (*Value_StringValue)(nil), + (*Value_StructValue)(nil), + (*Value_ProtoValue)(nil), + (*Value_BoolValue)(nil), + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[13].OneofWrappers = []interface{}{ + (*ArtifactStructType_Simple)(nil), + (*ArtifactStructType_UnionType)(nil), + (*ArtifactStructType_Intersection)(nil), + (*ArtifactStructType_List)(nil), + (*ArtifactStructType_None)(nil), + (*ArtifactStructType_Any)(nil), + (*ArtifactStructType_Tuple)(nil), + (*ArtifactStructType_Dict)(nil), + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[27].OneofWrappers = []interface{}{ + (*ConnectionConfig_FakeDatabase)(nil), + (*ConnectionConfig_Mysql)(nil), + (*ConnectionConfig_Sqlite)(nil), + (*ConnectionConfig_Postgresql)(nil), + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[34].OneofWrappers = []interface{}{ + (*LineageGraphQueryOptions_ArtifactsOptions)(nil), + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[35].OneofWrappers = []interface{}{ + (*LineageSubgraphQueryOptions_StartingArtifacts)(nil), + (*LineageSubgraphQueryOptions_StartingExecutions)(nil), + } + file_ml_metadata_proto_metadata_store_proto_msgTypes[40].OneofWrappers = []interface{}{ + (*Event_Path_Step_Index)(nil), + (*Event_Path_Step_Key)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ml_metadata_proto_metadata_store_proto_rawDesc, + NumEnums: 10, + NumMessages: 55, + NumExtensions: 1, + NumServices: 0, + }, + GoTypes: file_ml_metadata_proto_metadata_store_proto_goTypes, + DependencyIndexes: file_ml_metadata_proto_metadata_store_proto_depIdxs, + EnumInfos: file_ml_metadata_proto_metadata_store_proto_enumTypes, + MessageInfos: file_ml_metadata_proto_metadata_store_proto_msgTypes, + ExtensionInfos: file_ml_metadata_proto_metadata_store_proto_extTypes, + }.Build() + File_ml_metadata_proto_metadata_store_proto = out.File + file_ml_metadata_proto_metadata_store_proto_rawDesc = nil + file_ml_metadata_proto_metadata_store_proto_goTypes = nil + file_ml_metadata_proto_metadata_store_proto_depIdxs = nil +} diff --git a/pkg/ml_metadata/proto/metadata_store_service.pb.go b/pkg/ml_metadata/proto/metadata_store_service.pb.go new file mode 100644 index 00000000..23d7248b --- /dev/null +++ b/pkg/ml_metadata/proto/metadata_store_service.pb.go @@ -0,0 +1,10227 @@ +// Copyright 2019 Google LLC +// +//Licensed 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 +// +//https://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. +//============================================================================== + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.31.0 +// protoc v3.20.3 +// source: ml_metadata/proto/metadata_store_service.proto + +package proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// An artifact and type pair. Part of an artifact struct. +type ArtifactAndType struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Artifact *Artifact `protobuf:"bytes,1,opt,name=artifact" json:"artifact,omitempty"` + Type *ArtifactType `protobuf:"bytes,2,opt,name=type" json:"type,omitempty"` +} + +func (x *ArtifactAndType) Reset() { + *x = ArtifactAndType{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArtifactAndType) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArtifactAndType) ProtoMessage() {} + +func (x *ArtifactAndType) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArtifactAndType.ProtoReflect.Descriptor instead. +func (*ArtifactAndType) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{0} +} + +func (x *ArtifactAndType) GetArtifact() *Artifact { + if x != nil { + return x.Artifact + } + return nil +} + +func (x *ArtifactAndType) GetType() *ArtifactType { + if x != nil { + return x.Type + } + return nil +} + +// A dictionary of artifact structs. Can represent a dictionary. +type ArtifactStructMap struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // An artifact struct that is a dictionary. + // Can be represented as a JSON dictionary of artifact structs. + Properties map[string]*ArtifactStruct `protobuf:"bytes,1,rep,name=properties" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (x *ArtifactStructMap) Reset() { + *x = ArtifactStructMap{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArtifactStructMap) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArtifactStructMap) ProtoMessage() {} + +func (x *ArtifactStructMap) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArtifactStructMap.ProtoReflect.Descriptor instead. +func (*ArtifactStructMap) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{1} +} + +func (x *ArtifactStructMap) GetProperties() map[string]*ArtifactStruct { + if x != nil { + return x.Properties + } + return nil +} + +// An artifact struct that is a list. +type ArtifactStructList struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Can be represented as a JSON list of artifact structs. + Elements []*ArtifactStruct `protobuf:"bytes,1,rep,name=elements" json:"elements,omitempty"` +} + +func (x *ArtifactStructList) Reset() { + *x = ArtifactStructList{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArtifactStructList) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArtifactStructList) ProtoMessage() {} + +func (x *ArtifactStructList) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArtifactStructList.ProtoReflect.Descriptor instead. +func (*ArtifactStructList) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{2} +} + +func (x *ArtifactStructList) GetElements() []*ArtifactStruct { + if x != nil { + return x.Elements + } + return nil +} + +// An artifact struct represents the input or output of an Execution. +// See the more specific types referenced in the message for more details. +type ArtifactStruct struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Note: an artifact struct may be empty to indicate "None" or null. + // + // Types that are assignable to Value: + // + // *ArtifactStruct_Artifact + // *ArtifactStruct_Map + // *ArtifactStruct_List + Value isArtifactStruct_Value `protobuf_oneof:"value"` +} + +func (x *ArtifactStruct) Reset() { + *x = ArtifactStruct{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ArtifactStruct) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ArtifactStruct) ProtoMessage() {} + +func (x *ArtifactStruct) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ArtifactStruct.ProtoReflect.Descriptor instead. +func (*ArtifactStruct) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{3} +} + +func (m *ArtifactStruct) GetValue() isArtifactStruct_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *ArtifactStruct) GetArtifact() *ArtifactAndType { + if x, ok := x.GetValue().(*ArtifactStruct_Artifact); ok { + return x.Artifact + } + return nil +} + +func (x *ArtifactStruct) GetMap() *ArtifactStructMap { + if x, ok := x.GetValue().(*ArtifactStruct_Map); ok { + return x.Map + } + return nil +} + +func (x *ArtifactStruct) GetList() *ArtifactStructList { + if x, ok := x.GetValue().(*ArtifactStruct_List); ok { + return x.List + } + return nil +} + +type isArtifactStruct_Value interface { + isArtifactStruct_Value() +} + +type ArtifactStruct_Artifact struct { + Artifact *ArtifactAndType `protobuf:"bytes,1,opt,name=artifact,oneof"` +} + +type ArtifactStruct_Map struct { + Map *ArtifactStructMap `protobuf:"bytes,2,opt,name=map,oneof"` +} + +type ArtifactStruct_List struct { + List *ArtifactStructList `protobuf:"bytes,3,opt,name=list,oneof"` +} + +func (*ArtifactStruct_Artifact) isArtifactStruct_Value() {} + +func (*ArtifactStruct_Map) isArtifactStruct_Value() {} + +func (*ArtifactStruct_List) isArtifactStruct_Value() {} + +type PutArtifactsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Artifacts []*Artifact `protobuf:"bytes,1,rep,name=artifacts" json:"artifacts,omitempty"` + // Additional options to change the behavior of the method. + Options *PutArtifactsRequest_Options `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` + // FieldMask for artifacts in the PUT update + // If `artifact.id` is not specified, it means a new artifact will be created + // and `update_mask` will not be applied to the creation. + // If `update_mask` is empty, update the artifacts as a whole. + // If `update_mask` is not empty, only update fields or properties specified + // in `update_mask`. + // Example request protos: + // 1. Examples that update `properties` / `custom_properties`: + // 1.1 Add a <'key', 'val'> pair into `custom_properties`: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // string_value: "val" + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 1.2 Set `custom_properties['key'].bool_value` to true: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // bool_value: true + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 1.3 Delete the complete <'key', 'val'> pair from `custom_properties`: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // custom_properties {} + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 2. Examples that update fields such as `uri`, `external_id`, etc: + // 2.1 Update `external_id` field: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // external_id: "new_value" + // } + // update_mask { + // paths: "external_id" + // } + // } + // 2.2 Set `uri` field: + // { + // artifacts { + // id: 1234 + // type_id: 5678 + // uri: "set_value" + // } + // update_mask { + // paths: "uri" + // } + // } + // + // If `paths: "properties"` or `paths: "custom_properties"` are added to + // `update_mask`, the key-level updates will be ignored and we only perform + // field-level updates on the all `properties`/`custom_properties`. + // For example: + // + // If the mask is: {"properties", "properties.key1"}, the field path + // "properties.key1" will be ignored and all `properties` will be updated. + // (Do not suggest) + // If the mask is {"properties", "external_id"}, all + // `properties` and field `external_id` will be updated. (Do not suggest) + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,4,opt,name=update_mask,json=updateMask" json:"update_mask,omitempty"` +} + +func (x *PutArtifactsRequest) Reset() { + *x = PutArtifactsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutArtifactsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutArtifactsRequest) ProtoMessage() {} + +func (x *PutArtifactsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutArtifactsRequest.ProtoReflect.Descriptor instead. +func (*PutArtifactsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{4} +} + +func (x *PutArtifactsRequest) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +func (x *PutArtifactsRequest) GetOptions() *PutArtifactsRequest_Options { + if x != nil { + return x.Options + } + return nil +} + +func (x *PutArtifactsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +func (x *PutArtifactsRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type PutArtifactsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of artifact ids index-aligned with PutArtifactsRequest. + ArtifactIds []int64 `protobuf:"varint,1,rep,name=artifact_ids,json=artifactIds" json:"artifact_ids,omitempty"` +} + +func (x *PutArtifactsResponse) Reset() { + *x = PutArtifactsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutArtifactsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutArtifactsResponse) ProtoMessage() {} + +func (x *PutArtifactsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutArtifactsResponse.ProtoReflect.Descriptor instead. +func (*PutArtifactsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{5} +} + +func (x *PutArtifactsResponse) GetArtifactIds() []int64 { + if x != nil { + return x.ArtifactIds + } + return nil +} + +type PutArtifactTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The field is required in any request. Stored types in MLMD can be updated + // by introducing new properties and remain backward compatible. If a type + // with the same name exists in the database, it updates the existing type, + // otherwise it creates a new type. + ArtifactType *ArtifactType `protobuf:"bytes,1,opt,name=artifact_type,json=artifactType" json:"artifact_type,omitempty"` + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + CanAddFields *bool `protobuf:"varint,2,opt,name=can_add_fields,json=canAddFields" json:"can_add_fields,omitempty"` + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + CanOmitFields *bool `protobuf:"varint,5,opt,name=can_omit_fields,json=canOmitFields" json:"can_omit_fields,omitempty"` + // Deprecated fields. + // + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + CanDeleteFields *bool `protobuf:"varint,3,opt,name=can_delete_fields,json=canDeleteFields" json:"can_delete_fields,omitempty"` + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + AllFieldsMatch *bool `protobuf:"varint,4,opt,name=all_fields_match,json=allFieldsMatch,def=1" json:"all_fields_match,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,6,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +// Default values for PutArtifactTypeRequest fields. +const ( + Default_PutArtifactTypeRequest_AllFieldsMatch = bool(true) +) + +func (x *PutArtifactTypeRequest) Reset() { + *x = PutArtifactTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutArtifactTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutArtifactTypeRequest) ProtoMessage() {} + +func (x *PutArtifactTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutArtifactTypeRequest.ProtoReflect.Descriptor instead. +func (*PutArtifactTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{6} +} + +func (x *PutArtifactTypeRequest) GetArtifactType() *ArtifactType { + if x != nil { + return x.ArtifactType + } + return nil +} + +func (x *PutArtifactTypeRequest) GetCanAddFields() bool { + if x != nil && x.CanAddFields != nil { + return *x.CanAddFields + } + return false +} + +func (x *PutArtifactTypeRequest) GetCanOmitFields() bool { + if x != nil && x.CanOmitFields != nil { + return *x.CanOmitFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutArtifactTypeRequest) GetCanDeleteFields() bool { + if x != nil && x.CanDeleteFields != nil { + return *x.CanDeleteFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutArtifactTypeRequest) GetAllFieldsMatch() bool { + if x != nil && x.AllFieldsMatch != nil { + return *x.AllFieldsMatch + } + return Default_PutArtifactTypeRequest_AllFieldsMatch +} + +func (x *PutArtifactTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutArtifactTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The type ID of the artifact type. + TypeId *int64 `protobuf:"varint,1,opt,name=type_id,json=typeId" json:"type_id,omitempty"` +} + +func (x *PutArtifactTypeResponse) Reset() { + *x = PutArtifactTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutArtifactTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutArtifactTypeResponse) ProtoMessage() {} + +func (x *PutArtifactTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutArtifactTypeResponse.ProtoReflect.Descriptor instead. +func (*PutArtifactTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{7} +} + +func (x *PutArtifactTypeResponse) GetTypeId() int64 { + if x != nil && x.TypeId != nil { + return *x.TypeId + } + return 0 +} + +type PutExecutionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Executions []*Execution `protobuf:"bytes,1,rep,name=executions" json:"executions,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` + // FieldMask for executions in the PUT update + // If `execution.id` is not specified, it means a new execution will be + // created and `update_mask` will not be applied to the creation. + // If `update_mask` is empty, update the executions as a whole. + // If `update_mask` is not empty, only update fields or properties specified + // in `update_mask`. + // Example request protos: + // 1. Add a <'key', 'val'> pair into `custom_properties`: + // { + // executions { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // string_value: "val" + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 2. Set `last_known_state` field: + // { + // executions { + // id: 1234 + // type_id: 5678 + // last_known_state: CACHED + // } + // update_mask { + // paths: "last_known_state" + // } + // } + // + // Please refer to `PutArtifactsRequest` for more details. + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,3,opt,name=update_mask,json=updateMask" json:"update_mask,omitempty"` +} + +func (x *PutExecutionsRequest) Reset() { + *x = PutExecutionsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionsRequest) ProtoMessage() {} + +func (x *PutExecutionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionsRequest.ProtoReflect.Descriptor instead. +func (*PutExecutionsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{8} +} + +func (x *PutExecutionsRequest) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +func (x *PutExecutionsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +func (x *PutExecutionsRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type PutExecutionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of execution ids index-aligned with PutExecutionsRequest. + ExecutionIds []int64 `protobuf:"varint,1,rep,name=execution_ids,json=executionIds" json:"execution_ids,omitempty"` +} + +func (x *PutExecutionsResponse) Reset() { + *x = PutExecutionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionsResponse) ProtoMessage() {} + +func (x *PutExecutionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionsResponse.ProtoReflect.Descriptor instead. +func (*PutExecutionsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{9} +} + +func (x *PutExecutionsResponse) GetExecutionIds() []int64 { + if x != nil { + return x.ExecutionIds + } + return nil +} + +type PutExecutionTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The field is required in any request. Stored types in MLMD can be updated + // by introducing new properties and remain backward compatible. If a type + // with the same name exists in the database, it updates the existing type, + // otherwise it creates a new type. + ExecutionType *ExecutionType `protobuf:"bytes,1,opt,name=execution_type,json=executionType" json:"execution_type,omitempty"` + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + CanAddFields *bool `protobuf:"varint,2,opt,name=can_add_fields,json=canAddFields" json:"can_add_fields,omitempty"` + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + CanOmitFields *bool `protobuf:"varint,5,opt,name=can_omit_fields,json=canOmitFields" json:"can_omit_fields,omitempty"` + // Deprecated fields. + // + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + CanDeleteFields *bool `protobuf:"varint,3,opt,name=can_delete_fields,json=canDeleteFields" json:"can_delete_fields,omitempty"` + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + AllFieldsMatch *bool `protobuf:"varint,4,opt,name=all_fields_match,json=allFieldsMatch,def=1" json:"all_fields_match,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,6,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +// Default values for PutExecutionTypeRequest fields. +const ( + Default_PutExecutionTypeRequest_AllFieldsMatch = bool(true) +) + +func (x *PutExecutionTypeRequest) Reset() { + *x = PutExecutionTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionTypeRequest) ProtoMessage() {} + +func (x *PutExecutionTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionTypeRequest.ProtoReflect.Descriptor instead. +func (*PutExecutionTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{10} +} + +func (x *PutExecutionTypeRequest) GetExecutionType() *ExecutionType { + if x != nil { + return x.ExecutionType + } + return nil +} + +func (x *PutExecutionTypeRequest) GetCanAddFields() bool { + if x != nil && x.CanAddFields != nil { + return *x.CanAddFields + } + return false +} + +func (x *PutExecutionTypeRequest) GetCanOmitFields() bool { + if x != nil && x.CanOmitFields != nil { + return *x.CanOmitFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutExecutionTypeRequest) GetCanDeleteFields() bool { + if x != nil && x.CanDeleteFields != nil { + return *x.CanDeleteFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutExecutionTypeRequest) GetAllFieldsMatch() bool { + if x != nil && x.AllFieldsMatch != nil { + return *x.AllFieldsMatch + } + return Default_PutExecutionTypeRequest_AllFieldsMatch +} + +func (x *PutExecutionTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutExecutionTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The type ID of the execution type. + TypeId *int64 `protobuf:"varint,1,opt,name=type_id,json=typeId" json:"type_id,omitempty"` +} + +func (x *PutExecutionTypeResponse) Reset() { + *x = PutExecutionTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionTypeResponse) ProtoMessage() {} + +func (x *PutExecutionTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionTypeResponse.ProtoReflect.Descriptor instead. +func (*PutExecutionTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{11} +} + +func (x *PutExecutionTypeResponse) GetTypeId() int64 { + if x != nil && x.TypeId != nil { + return *x.TypeId + } + return 0 +} + +type PutEventsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Events []*Event `protobuf:"bytes,1,rep,name=events" json:"events,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *PutEventsRequest) Reset() { + *x = PutEventsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutEventsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutEventsRequest) ProtoMessage() {} + +func (x *PutEventsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutEventsRequest.ProtoReflect.Descriptor instead. +func (*PutEventsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{12} +} + +func (x *PutEventsRequest) GetEvents() []*Event { + if x != nil { + return x.Events + } + return nil +} + +func (x *PutEventsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutEventsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PutEventsResponse) Reset() { + *x = PutEventsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutEventsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutEventsResponse) ProtoMessage() {} + +func (x *PutEventsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutEventsResponse.ProtoReflect.Descriptor instead. +func (*PutEventsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{13} +} + +type PutExecutionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The execution that produces many artifact and event pairs. + Execution *Execution `protobuf:"bytes,1,opt,name=execution" json:"execution,omitempty"` + // The list of artifact and event pairs. + ArtifactEventPairs []*PutExecutionRequest_ArtifactAndEvent `protobuf:"bytes,2,rep,name=artifact_event_pairs,json=artifactEventPairs" json:"artifact_event_pairs,omitempty"` + // A list of contexts associated with the execution and artifacts. For each + // given context without a context.id, it inserts the context, otherwise it + // updates the stored context with the same id. + // Associations between each pair of contexts and the execution, and + // attributions between each pair of contexts and artifacts are created if + // they do not already exist. + Contexts []*Context `protobuf:"bytes,3,rep,name=contexts" json:"contexts,omitempty"` + // Additional options to change the behavior of the method. + Options *PutExecutionRequest_Options `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,5,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *PutExecutionRequest) Reset() { + *x = PutExecutionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionRequest) ProtoMessage() {} + +func (x *PutExecutionRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionRequest.ProtoReflect.Descriptor instead. +func (*PutExecutionRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{14} +} + +func (x *PutExecutionRequest) GetExecution() *Execution { + if x != nil { + return x.Execution + } + return nil +} + +func (x *PutExecutionRequest) GetArtifactEventPairs() []*PutExecutionRequest_ArtifactAndEvent { + if x != nil { + return x.ArtifactEventPairs + } + return nil +} + +func (x *PutExecutionRequest) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +func (x *PutExecutionRequest) GetOptions() *PutExecutionRequest_Options { + if x != nil { + return x.Options + } + return nil +} + +func (x *PutExecutionRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutExecutionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // An execution id of the `execution` in PutExecutionRequest. + ExecutionId *int64 `protobuf:"varint,1,opt,name=execution_id,json=executionId" json:"execution_id,omitempty"` + // A list of artifact ids index-aligned with `artifact_event_pairs` in the + // PutExecutionRequest. + ArtifactIds []int64 `protobuf:"varint,2,rep,name=artifact_ids,json=artifactIds" json:"artifact_ids,omitempty"` + // A list of context ids index-aligned with `contexts` in the + // PutExecutionRequest. + ContextIds []int64 `protobuf:"varint,3,rep,name=context_ids,json=contextIds" json:"context_ids,omitempty"` +} + +func (x *PutExecutionResponse) Reset() { + *x = PutExecutionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionResponse) ProtoMessage() {} + +func (x *PutExecutionResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionResponse.ProtoReflect.Descriptor instead. +func (*PutExecutionResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{15} +} + +func (x *PutExecutionResponse) GetExecutionId() int64 { + if x != nil && x.ExecutionId != nil { + return *x.ExecutionId + } + return 0 +} + +func (x *PutExecutionResponse) GetArtifactIds() []int64 { + if x != nil { + return x.ArtifactIds + } + return nil +} + +func (x *PutExecutionResponse) GetContextIds() []int64 { + if x != nil { + return x.ContextIds + } + return nil +} + +type PutLineageSubgraphRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Executions []*Execution `protobuf:"bytes,1,rep,name=executions" json:"executions,omitempty"` + Artifacts []*Artifact `protobuf:"bytes,2,rep,name=artifacts" json:"artifacts,omitempty"` + Contexts []*Context `protobuf:"bytes,3,rep,name=contexts" json:"contexts,omitempty"` + EventEdges []*PutLineageSubgraphRequest_EventEdge `protobuf:"bytes,4,rep,name=event_edges,json=eventEdges" json:"event_edges,omitempty"` + Options *PutLineageSubgraphRequest_Options `protobuf:"bytes,5,opt,name=options" json:"options,omitempty"` + TransactionOptions *TransactionOptions `protobuf:"bytes,6,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *PutLineageSubgraphRequest) Reset() { + *x = PutLineageSubgraphRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutLineageSubgraphRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutLineageSubgraphRequest) ProtoMessage() {} + +func (x *PutLineageSubgraphRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutLineageSubgraphRequest.ProtoReflect.Descriptor instead. +func (*PutLineageSubgraphRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{16} +} + +func (x *PutLineageSubgraphRequest) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +func (x *PutLineageSubgraphRequest) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +func (x *PutLineageSubgraphRequest) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +func (x *PutLineageSubgraphRequest) GetEventEdges() []*PutLineageSubgraphRequest_EventEdge { + if x != nil { + return x.EventEdges + } + return nil +} + +func (x *PutLineageSubgraphRequest) GetOptions() *PutLineageSubgraphRequest_Options { + if x != nil { + return x.Options + } + return nil +} + +func (x *PutLineageSubgraphRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutLineageSubgraphResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of execution ids index-aligned with `executions` in the request + ExecutionIds []int64 `protobuf:"varint,1,rep,packed,name=execution_ids,json=executionIds" json:"execution_ids,omitempty"` + // A list of artifact ids index-aligned with `artifacts` in the request + ArtifactIds []int64 `protobuf:"varint,2,rep,packed,name=artifact_ids,json=artifactIds" json:"artifact_ids,omitempty"` + // A list of context ids index-aligned with `contexts` in the request + ContextIds []int64 `protobuf:"varint,3,rep,packed,name=context_ids,json=contextIds" json:"context_ids,omitempty"` +} + +func (x *PutLineageSubgraphResponse) Reset() { + *x = PutLineageSubgraphResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutLineageSubgraphResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutLineageSubgraphResponse) ProtoMessage() {} + +func (x *PutLineageSubgraphResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutLineageSubgraphResponse.ProtoReflect.Descriptor instead. +func (*PutLineageSubgraphResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{17} +} + +func (x *PutLineageSubgraphResponse) GetExecutionIds() []int64 { + if x != nil { + return x.ExecutionIds + } + return nil +} + +func (x *PutLineageSubgraphResponse) GetArtifactIds() []int64 { + if x != nil { + return x.ArtifactIds + } + return nil +} + +func (x *PutLineageSubgraphResponse) GetContextIds() []int64 { + if x != nil { + return x.ContextIds + } + return nil +} + +type PutTypesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ArtifactTypes []*ArtifactType `protobuf:"bytes,1,rep,name=artifact_types,json=artifactTypes" json:"artifact_types,omitempty"` + ExecutionTypes []*ExecutionType `protobuf:"bytes,2,rep,name=execution_types,json=executionTypes" json:"execution_types,omitempty"` + ContextTypes []*ContextType `protobuf:"bytes,3,rep,name=context_types,json=contextTypes" json:"context_types,omitempty"` + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + CanAddFields *bool `protobuf:"varint,4,opt,name=can_add_fields,json=canAddFields" json:"can_add_fields,omitempty"` + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + CanOmitFields *bool `protobuf:"varint,7,opt,name=can_omit_fields,json=canOmitFields" json:"can_omit_fields,omitempty"` + // Deprecated fields. + // + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + CanDeleteFields *bool `protobuf:"varint,5,opt,name=can_delete_fields,json=canDeleteFields" json:"can_delete_fields,omitempty"` + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + AllFieldsMatch *bool `protobuf:"varint,6,opt,name=all_fields_match,json=allFieldsMatch,def=1" json:"all_fields_match,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,8,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +// Default values for PutTypesRequest fields. +const ( + Default_PutTypesRequest_AllFieldsMatch = bool(true) +) + +func (x *PutTypesRequest) Reset() { + *x = PutTypesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutTypesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutTypesRequest) ProtoMessage() {} + +func (x *PutTypesRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutTypesRequest.ProtoReflect.Descriptor instead. +func (*PutTypesRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{18} +} + +func (x *PutTypesRequest) GetArtifactTypes() []*ArtifactType { + if x != nil { + return x.ArtifactTypes + } + return nil +} + +func (x *PutTypesRequest) GetExecutionTypes() []*ExecutionType { + if x != nil { + return x.ExecutionTypes + } + return nil +} + +func (x *PutTypesRequest) GetContextTypes() []*ContextType { + if x != nil { + return x.ContextTypes + } + return nil +} + +func (x *PutTypesRequest) GetCanAddFields() bool { + if x != nil && x.CanAddFields != nil { + return *x.CanAddFields + } + return false +} + +func (x *PutTypesRequest) GetCanOmitFields() bool { + if x != nil && x.CanOmitFields != nil { + return *x.CanOmitFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutTypesRequest) GetCanDeleteFields() bool { + if x != nil && x.CanDeleteFields != nil { + return *x.CanDeleteFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutTypesRequest) GetAllFieldsMatch() bool { + if x != nil && x.AllFieldsMatch != nil { + return *x.AllFieldsMatch + } + return Default_PutTypesRequest_AllFieldsMatch +} + +func (x *PutTypesRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutTypesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The type ids of the artifact type. + ArtifactTypeIds []int64 `protobuf:"varint,1,rep,name=artifact_type_ids,json=artifactTypeIds" json:"artifact_type_ids,omitempty"` + // The type ids of the execution type. + ExecutionTypeIds []int64 `protobuf:"varint,2,rep,name=execution_type_ids,json=executionTypeIds" json:"execution_type_ids,omitempty"` + // The type ids of the context type. + ContextTypeIds []int64 `protobuf:"varint,3,rep,name=context_type_ids,json=contextTypeIds" json:"context_type_ids,omitempty"` +} + +func (x *PutTypesResponse) Reset() { + *x = PutTypesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutTypesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutTypesResponse) ProtoMessage() {} + +func (x *PutTypesResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutTypesResponse.ProtoReflect.Descriptor instead. +func (*PutTypesResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{19} +} + +func (x *PutTypesResponse) GetArtifactTypeIds() []int64 { + if x != nil { + return x.ArtifactTypeIds + } + return nil +} + +func (x *PutTypesResponse) GetExecutionTypeIds() []int64 { + if x != nil { + return x.ExecutionTypeIds + } + return nil +} + +func (x *PutTypesResponse) GetContextTypeIds() []int64 { + if x != nil { + return x.ContextTypeIds + } + return nil +} + +type PutContextTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The field is required in any request. Stored types in MLMD can be updated + // by introducing new properties and remain backward compatible. If a type + // with the same name exists in the database, it updates the existing type, + // otherwise it creates a new type. + ContextType *ContextType `protobuf:"bytes,1,opt,name=context_type,json=contextType" json:"context_type,omitempty"` + // If true then allows adding properties to an existing stored type. + // If false, then type update is not allowed and it raises AlreadyExists + // error if the given type has any new property that is not defined in the + // stored type. + CanAddFields *bool `protobuf:"varint,2,opt,name=can_add_fields,json=canAddFields" json:"can_add_fields,omitempty"` + // If true then allows omitting properties of an existing stored type. + // If false, then no properties of the stored type can be omitted in the + // given type, otherwise it raises AlreadyExists error. + CanOmitFields *bool `protobuf:"varint,5,opt,name=can_omit_fields,json=canOmitFields" json:"can_omit_fields,omitempty"` + // Deprecated fields. + // + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + CanDeleteFields *bool `protobuf:"varint,3,opt,name=can_delete_fields,json=canDeleteFields" json:"can_delete_fields,omitempty"` + // Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. + AllFieldsMatch *bool `protobuf:"varint,4,opt,name=all_fields_match,json=allFieldsMatch,def=1" json:"all_fields_match,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,6,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +// Default values for PutContextTypeRequest fields. +const ( + Default_PutContextTypeRequest_AllFieldsMatch = bool(true) +) + +func (x *PutContextTypeRequest) Reset() { + *x = PutContextTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutContextTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutContextTypeRequest) ProtoMessage() {} + +func (x *PutContextTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutContextTypeRequest.ProtoReflect.Descriptor instead. +func (*PutContextTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{20} +} + +func (x *PutContextTypeRequest) GetContextType() *ContextType { + if x != nil { + return x.ContextType + } + return nil +} + +func (x *PutContextTypeRequest) GetCanAddFields() bool { + if x != nil && x.CanAddFields != nil { + return *x.CanAddFields + } + return false +} + +func (x *PutContextTypeRequest) GetCanOmitFields() bool { + if x != nil && x.CanOmitFields != nil { + return *x.CanOmitFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutContextTypeRequest) GetCanDeleteFields() bool { + if x != nil && x.CanDeleteFields != nil { + return *x.CanDeleteFields + } + return false +} + +// Deprecated: Marked as deprecated in ml_metadata/proto/metadata_store_service.proto. +func (x *PutContextTypeRequest) GetAllFieldsMatch() bool { + if x != nil && x.AllFieldsMatch != nil { + return *x.AllFieldsMatch + } + return Default_PutContextTypeRequest_AllFieldsMatch +} + +func (x *PutContextTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutContextTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The type ID of the context type. + TypeId *int64 `protobuf:"varint,1,opt,name=type_id,json=typeId" json:"type_id,omitempty"` +} + +func (x *PutContextTypeResponse) Reset() { + *x = PutContextTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutContextTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutContextTypeResponse) ProtoMessage() {} + +func (x *PutContextTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutContextTypeResponse.ProtoReflect.Descriptor instead. +func (*PutContextTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{21} +} + +func (x *PutContextTypeResponse) GetTypeId() int64 { + if x != nil && x.TypeId != nil { + return *x.TypeId + } + return 0 +} + +type PutContextsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` + // FieldMask for contexts in the PUT update + // If `context.id` is not specified, it means a new context will be + // created and `update_mask` will not be applied to the creation. + // If `update_mask` is empty, update the contexts as a whole. + // If `update_mask` is not empty, only update fields or properties specified + // in `update_mask`. + // Example request protos: + // 1. Add a <'key', 'val'> pair into `custom_properties`: + // { + // contexts { + // id: 1234 + // type_id: 5678 + // custom_properties { + // key: "key" + // value: { + // string_value: "val" + // } + // } + // } + // update_mask { + // paths: "custom_properties.key" + // } + // } + // 2. Set `name` field: + // { + // contexts { + // id: 1234 + // type_id: 5678 + // name: "set_name" + // } + // update_mask { + // paths: "name" + // } + // } + // + // Please refer to `PutArtifactsRequest` for more details. + UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,3,opt,name=update_mask,json=updateMask" json:"update_mask,omitempty"` +} + +func (x *PutContextsRequest) Reset() { + *x = PutContextsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutContextsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutContextsRequest) ProtoMessage() {} + +func (x *PutContextsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutContextsRequest.ProtoReflect.Descriptor instead. +func (*PutContextsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{22} +} + +func (x *PutContextsRequest) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +func (x *PutContextsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +func (x *PutContextsRequest) GetUpdateMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.UpdateMask + } + return nil +} + +type PutContextsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of context ids index-aligned with PutContextsRequest. + ContextIds []int64 `protobuf:"varint,1,rep,name=context_ids,json=contextIds" json:"context_ids,omitempty"` +} + +func (x *PutContextsResponse) Reset() { + *x = PutContextsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutContextsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutContextsResponse) ProtoMessage() {} + +func (x *PutContextsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutContextsResponse.ProtoReflect.Descriptor instead. +func (*PutContextsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{23} +} + +func (x *PutContextsResponse) GetContextIds() []int64 { + if x != nil { + return x.ContextIds + } + return nil +} + +type PutAttributionsAndAssociationsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Attributions []*Attribution `protobuf:"bytes,1,rep,name=attributions" json:"attributions,omitempty"` + Associations []*Association `protobuf:"bytes,2,rep,name=associations" json:"associations,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *PutAttributionsAndAssociationsRequest) Reset() { + *x = PutAttributionsAndAssociationsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutAttributionsAndAssociationsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutAttributionsAndAssociationsRequest) ProtoMessage() {} + +func (x *PutAttributionsAndAssociationsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutAttributionsAndAssociationsRequest.ProtoReflect.Descriptor instead. +func (*PutAttributionsAndAssociationsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{24} +} + +func (x *PutAttributionsAndAssociationsRequest) GetAttributions() []*Attribution { + if x != nil { + return x.Attributions + } + return nil +} + +func (x *PutAttributionsAndAssociationsRequest) GetAssociations() []*Association { + if x != nil { + return x.Associations + } + return nil +} + +func (x *PutAttributionsAndAssociationsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutAttributionsAndAssociationsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PutAttributionsAndAssociationsResponse) Reset() { + *x = PutAttributionsAndAssociationsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutAttributionsAndAssociationsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutAttributionsAndAssociationsResponse) ProtoMessage() {} + +func (x *PutAttributionsAndAssociationsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutAttributionsAndAssociationsResponse.ProtoReflect.Descriptor instead. +func (*PutAttributionsAndAssociationsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{25} +} + +type PutParentContextsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ParentContexts []*ParentContext `protobuf:"bytes,1,rep,name=parent_contexts,json=parentContexts" json:"parent_contexts,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *PutParentContextsRequest) Reset() { + *x = PutParentContextsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutParentContextsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutParentContextsRequest) ProtoMessage() {} + +func (x *PutParentContextsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutParentContextsRequest.ProtoReflect.Descriptor instead. +func (*PutParentContextsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{26} +} + +func (x *PutParentContextsRequest) GetParentContexts() []*ParentContext { + if x != nil { + return x.ParentContexts + } + return nil +} + +func (x *PutParentContextsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type PutParentContextsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PutParentContextsResponse) Reset() { + *x = PutParentContextsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutParentContextsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutParentContextsResponse) ProtoMessage() {} + +func (x *PutParentContextsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutParentContextsResponse.ProtoReflect.Descriptor instead. +func (*PutParentContextsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{27} +} + +type GetArtifactsByTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name with default type_version. + TypeVersion *string `protobuf:"bytes,2,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + // + // If set, the request will + // + // first fetch all artifacts with specified `type_name` and `type_version`, + // then order by a specifield field + // finally find the correct page and return #Artifacts of the page size. + // + // Higher-level APIs may only use the functionalies partially. + // Please reference the API documentation for the API behaviors. + Options *ListOperationOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,4,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactsByTypeRequest) Reset() { + *x = GetArtifactsByTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByTypeRequest) ProtoMessage() {} + +func (x *GetArtifactsByTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByTypeRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactsByTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{28} +} + +func (x *GetArtifactsByTypeRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetArtifactsByTypeRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetArtifactsByTypeRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetArtifactsByTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactsByTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Artifacts []*Artifact `protobuf:"bytes,1,rep,name=artifacts" json:"artifacts,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (x *GetArtifactsByTypeResponse) Reset() { + *x = GetArtifactsByTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByTypeResponse) ProtoMessage() {} + +func (x *GetArtifactsByTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByTypeResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactsByTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{29} +} + +func (x *GetArtifactsByTypeResponse) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +func (x *GetArtifactsByTypeResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +type GetArtifactByTypeAndNameRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name and artifact_name with + // default type_version. + TypeVersion *string `protobuf:"bytes,3,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + ArtifactName *string `protobuf:"bytes,2,opt,name=artifact_name,json=artifactName" json:"artifact_name,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,4,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactByTypeAndNameRequest) Reset() { + *x = GetArtifactByTypeAndNameRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactByTypeAndNameRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactByTypeAndNameRequest) ProtoMessage() {} + +func (x *GetArtifactByTypeAndNameRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactByTypeAndNameRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactByTypeAndNameRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{30} +} + +func (x *GetArtifactByTypeAndNameRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetArtifactByTypeAndNameRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetArtifactByTypeAndNameRequest) GetArtifactName() string { + if x != nil && x.ArtifactName != nil { + return *x.ArtifactName + } + return "" +} + +func (x *GetArtifactByTypeAndNameRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactByTypeAndNameResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Artifact *Artifact `protobuf:"bytes,1,opt,name=artifact" json:"artifact,omitempty"` +} + +func (x *GetArtifactByTypeAndNameResponse) Reset() { + *x = GetArtifactByTypeAndNameResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactByTypeAndNameResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactByTypeAndNameResponse) ProtoMessage() {} + +func (x *GetArtifactByTypeAndNameResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactByTypeAndNameResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactByTypeAndNameResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{31} +} + +func (x *GetArtifactByTypeAndNameResponse) GetArtifact() *Artifact { + if x != nil { + return x.Artifact + } + return nil +} + +type GetArtifactsByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of artifact ids to retrieve. + ArtifactIds []int64 `protobuf:"varint,1,rep,name=artifact_ids,json=artifactIds" json:"artifact_ids,omitempty"` + // An option to populate all the ArtifactTypes in the response. + // If true, returns retrieved Artifacts and their artifact types, which can be + // matched by type_ids. + // If false, returns only the retrieved Artifacts. + // Example request proto: + // + // { + // artifact_ids: 101, + // populate_artifact_types: true, + // } + // The response will contain an artifact with id = 101 and an artifact type + // with id = artifact.type_id(). + PopulateArtifactTypes *bool `protobuf:"varint,3,opt,name=populate_artifact_types,json=populateArtifactTypes,def=0" json:"populate_artifact_types,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +// Default values for GetArtifactsByIDRequest fields. +const ( + Default_GetArtifactsByIDRequest_PopulateArtifactTypes = bool(false) +) + +func (x *GetArtifactsByIDRequest) Reset() { + *x = GetArtifactsByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByIDRequest) ProtoMessage() {} + +func (x *GetArtifactsByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByIDRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactsByIDRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{32} +} + +func (x *GetArtifactsByIDRequest) GetArtifactIds() []int64 { + if x != nil { + return x.ArtifactIds + } + return nil +} + +func (x *GetArtifactsByIDRequest) GetPopulateArtifactTypes() bool { + if x != nil && x.PopulateArtifactTypes != nil { + return *x.PopulateArtifactTypes + } + return Default_GetArtifactsByIDRequest_PopulateArtifactTypes +} + +func (x *GetArtifactsByIDRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactsByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Artifacts with matching ids. + // This is not index-aligned: if an id is not found, it is not returned. + Artifacts []*Artifact `protobuf:"bytes,1,rep,name=artifacts" json:"artifacts,omitempty"` + // ArtifactTypes populated with matching type_ids owned by `artifacts`. + // This is not index-aligned: if a type_id is not found, it is not returned. + ArtifactTypes []*ArtifactType `protobuf:"bytes,2,rep,name=artifact_types,json=artifactTypes" json:"artifact_types,omitempty"` +} + +func (x *GetArtifactsByIDResponse) Reset() { + *x = GetArtifactsByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByIDResponse) ProtoMessage() {} + +func (x *GetArtifactsByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByIDResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactsByIDResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{33} +} + +func (x *GetArtifactsByIDResponse) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +func (x *GetArtifactsByIDResponse) GetArtifactTypes() []*ArtifactType { + if x != nil { + return x.ArtifactTypes + } + return nil +} + +// Request to retrieve Artifacts using List options. +// If option is not specified then all Artifacts are returned. +type GetArtifactsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Specify options. + // Please refer to the documentation of ListOperationOptions for the supported + // functionalities. + Options *ListOperationOptions `protobuf:"bytes,1,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactsRequest) Reset() { + *x = GetArtifactsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsRequest) ProtoMessage() {} + +func (x *GetArtifactsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{34} +} + +func (x *GetArtifactsRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetArtifactsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Returned artifacts. + Artifacts []*Artifact `protobuf:"bytes,1,rep,name=artifacts" json:"artifacts,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (x *GetArtifactsResponse) Reset() { + *x = GetArtifactsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsResponse) ProtoMessage() {} + +func (x *GetArtifactsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{35} +} + +func (x *GetArtifactsResponse) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +func (x *GetArtifactsResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +type GetArtifactsByURIRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of artifact uris to retrieve. + Uris []string `protobuf:"bytes,2,rep,name=uris" json:"uris,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactsByURIRequest) Reset() { + *x = GetArtifactsByURIRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByURIRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByURIRequest) ProtoMessage() {} + +func (x *GetArtifactsByURIRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByURIRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactsByURIRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{36} +} + +func (x *GetArtifactsByURIRequest) GetUris() []string { + if x != nil { + return x.Uris + } + return nil +} + +func (x *GetArtifactsByURIRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactsByURIResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Artifacts []*Artifact `protobuf:"bytes,1,rep,name=artifacts" json:"artifacts,omitempty"` +} + +func (x *GetArtifactsByURIResponse) Reset() { + *x = GetArtifactsByURIResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByURIResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByURIResponse) ProtoMessage() {} + +func (x *GetArtifactsByURIResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByURIResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactsByURIResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{37} +} + +func (x *GetArtifactsByURIResponse) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +// Request to retrieve Executions using List options. +// If option is not specified then all Executions are returned. +type GetExecutionsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Specify options. + // Please refer to the documentation of ListOperationOptions for the supported + // functionalities. + Options *ListOperationOptions `protobuf:"bytes,1,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionsRequest) Reset() { + *x = GetExecutionsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsRequest) ProtoMessage() {} + +func (x *GetExecutionsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{38} +} + +func (x *GetExecutionsRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetExecutionsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Returned executions. + Executions []*Execution `protobuf:"bytes,1,rep,name=executions" json:"executions,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (x *GetExecutionsResponse) Reset() { + *x = GetExecutionsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[39] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsResponse) ProtoMessage() {} + +func (x *GetExecutionsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[39] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{39} +} + +func (x *GetExecutionsResponse) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +func (x *GetExecutionsResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +type GetArtifactTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name with default type_version. + TypeVersion *string `protobuf:"bytes,2,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactTypeRequest) Reset() { + *x = GetArtifactTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[40] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypeRequest) ProtoMessage() {} + +func (x *GetArtifactTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[40] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypeRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{40} +} + +func (x *GetArtifactTypeRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetArtifactTypeRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetArtifactTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Gets an artifact type, or clear if it does not exist. + ArtifactType *ArtifactType `protobuf:"bytes,1,opt,name=artifact_type,json=artifactType" json:"artifact_type,omitempty"` +} + +func (x *GetArtifactTypeResponse) Reset() { + *x = GetArtifactTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[41] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypeResponse) ProtoMessage() {} + +func (x *GetArtifactTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[41] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypeResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{41} +} + +func (x *GetArtifactTypeResponse) GetArtifactType() *ArtifactType { + if x != nil { + return x.ArtifactType + } + return nil +} + +type GetArtifactTypesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,1,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactTypesRequest) Reset() { + *x = GetArtifactTypesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[42] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypesRequest) ProtoMessage() {} + +func (x *GetArtifactTypesRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[42] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypesRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactTypesRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{42} +} + +func (x *GetArtifactTypesRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactTypesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ArtifactTypes []*ArtifactType `protobuf:"bytes,1,rep,name=artifact_types,json=artifactTypes" json:"artifact_types,omitempty"` +} + +func (x *GetArtifactTypesResponse) Reset() { + *x = GetArtifactTypesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[43] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypesResponse) ProtoMessage() {} + +func (x *GetArtifactTypesResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[43] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypesResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactTypesResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{43} +} + +func (x *GetArtifactTypesResponse) GetArtifactTypes() []*ArtifactType { + if x != nil { + return x.ArtifactTypes + } + return nil +} + +type GetExecutionTypesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,1,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionTypesRequest) Reset() { + *x = GetExecutionTypesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[44] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypesRequest) ProtoMessage() {} + +func (x *GetExecutionTypesRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[44] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypesRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionTypesRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{44} +} + +func (x *GetExecutionTypesRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionTypesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionTypes []*ExecutionType `protobuf:"bytes,1,rep,name=execution_types,json=executionTypes" json:"execution_types,omitempty"` +} + +func (x *GetExecutionTypesResponse) Reset() { + *x = GetExecutionTypesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypesResponse) ProtoMessage() {} + +func (x *GetExecutionTypesResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypesResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionTypesResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{45} +} + +func (x *GetExecutionTypesResponse) GetExecutionTypes() []*ExecutionType { + if x != nil { + return x.ExecutionTypes + } + return nil +} + +type GetContextTypesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,1,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextTypesRequest) Reset() { + *x = GetContextTypesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypesRequest) ProtoMessage() {} + +func (x *GetContextTypesRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypesRequest.ProtoReflect.Descriptor instead. +func (*GetContextTypesRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{46} +} + +func (x *GetContextTypesRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextTypesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextTypes []*ContextType `protobuf:"bytes,1,rep,name=context_types,json=contextTypes" json:"context_types,omitempty"` +} + +func (x *GetContextTypesResponse) Reset() { + *x = GetContextTypesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[47] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypesResponse) ProtoMessage() {} + +func (x *GetContextTypesResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[47] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypesResponse.ProtoReflect.Descriptor instead. +func (*GetContextTypesResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{47} +} + +func (x *GetContextTypesResponse) GetContextTypes() []*ContextType { + if x != nil { + return x.ContextTypes + } + return nil +} + +type GetArtifactsByExternalIdsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExternalIds []string `protobuf:"bytes,1,rep,name=external_ids,json=externalIds" json:"external_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactsByExternalIdsRequest) Reset() { + *x = GetArtifactsByExternalIdsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[48] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByExternalIdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByExternalIdsRequest) ProtoMessage() {} + +func (x *GetArtifactsByExternalIdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[48] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByExternalIdsRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactsByExternalIdsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{48} +} + +func (x *GetArtifactsByExternalIdsRequest) GetExternalIds() []string { + if x != nil { + return x.ExternalIds + } + return nil +} + +func (x *GetArtifactsByExternalIdsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactsByExternalIdsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Artifacts []*Artifact `protobuf:"bytes,1,rep,name=artifacts" json:"artifacts,omitempty"` +} + +func (x *GetArtifactsByExternalIdsResponse) Reset() { + *x = GetArtifactsByExternalIdsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[49] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByExternalIdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByExternalIdsResponse) ProtoMessage() {} + +func (x *GetArtifactsByExternalIdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[49] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByExternalIdsResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactsByExternalIdsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{49} +} + +func (x *GetArtifactsByExternalIdsResponse) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +type GetExecutionsByExternalIdsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExternalIds []string `protobuf:"bytes,1,rep,name=external_ids,json=externalIds" json:"external_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionsByExternalIdsRequest) Reset() { + *x = GetExecutionsByExternalIdsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[50] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByExternalIdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByExternalIdsRequest) ProtoMessage() {} + +func (x *GetExecutionsByExternalIdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[50] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByExternalIdsRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionsByExternalIdsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{50} +} + +func (x *GetExecutionsByExternalIdsRequest) GetExternalIds() []string { + if x != nil { + return x.ExternalIds + } + return nil +} + +func (x *GetExecutionsByExternalIdsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionsByExternalIdsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Executions []*Execution `protobuf:"bytes,1,rep,name=executions" json:"executions,omitempty"` +} + +func (x *GetExecutionsByExternalIdsResponse) Reset() { + *x = GetExecutionsByExternalIdsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[51] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByExternalIdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByExternalIdsResponse) ProtoMessage() {} + +func (x *GetExecutionsByExternalIdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[51] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByExternalIdsResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionsByExternalIdsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{51} +} + +func (x *GetExecutionsByExternalIdsResponse) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +type GetContextsByExternalIdsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExternalIds []string `protobuf:"bytes,1,rep,name=external_ids,json=externalIds" json:"external_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextsByExternalIdsRequest) Reset() { + *x = GetContextsByExternalIdsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByExternalIdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByExternalIdsRequest) ProtoMessage() {} + +func (x *GetContextsByExternalIdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[52] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByExternalIdsRequest.ProtoReflect.Descriptor instead. +func (*GetContextsByExternalIdsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{52} +} + +func (x *GetContextsByExternalIdsRequest) GetExternalIds() []string { + if x != nil { + return x.ExternalIds + } + return nil +} + +func (x *GetContextsByExternalIdsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextsByExternalIdsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` +} + +func (x *GetContextsByExternalIdsResponse) Reset() { + *x = GetContextsByExternalIdsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[53] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByExternalIdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByExternalIdsResponse) ProtoMessage() {} + +func (x *GetContextsByExternalIdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[53] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByExternalIdsResponse.ProtoReflect.Descriptor instead. +func (*GetContextsByExternalIdsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{53} +} + +func (x *GetContextsByExternalIdsResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +type GetArtifactTypesByExternalIdsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExternalIds []string `protobuf:"bytes,1,rep,name=external_ids,json=externalIds" json:"external_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactTypesByExternalIdsRequest) Reset() { + *x = GetArtifactTypesByExternalIdsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[54] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypesByExternalIdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypesByExternalIdsRequest) ProtoMessage() {} + +func (x *GetArtifactTypesByExternalIdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[54] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypesByExternalIdsRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactTypesByExternalIdsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{54} +} + +func (x *GetArtifactTypesByExternalIdsRequest) GetExternalIds() []string { + if x != nil { + return x.ExternalIds + } + return nil +} + +func (x *GetArtifactTypesByExternalIdsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactTypesByExternalIdsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ArtifactTypes []*ArtifactType `protobuf:"bytes,1,rep,name=artifact_types,json=artifactTypes" json:"artifact_types,omitempty"` +} + +func (x *GetArtifactTypesByExternalIdsResponse) Reset() { + *x = GetArtifactTypesByExternalIdsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypesByExternalIdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypesByExternalIdsResponse) ProtoMessage() {} + +func (x *GetArtifactTypesByExternalIdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[55] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypesByExternalIdsResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactTypesByExternalIdsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{55} +} + +func (x *GetArtifactTypesByExternalIdsResponse) GetArtifactTypes() []*ArtifactType { + if x != nil { + return x.ArtifactTypes + } + return nil +} + +type GetExecutionTypesByExternalIdsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExternalIds []string `protobuf:"bytes,1,rep,name=external_ids,json=externalIds" json:"external_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionTypesByExternalIdsRequest) Reset() { + *x = GetExecutionTypesByExternalIdsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypesByExternalIdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypesByExternalIdsRequest) ProtoMessage() {} + +func (x *GetExecutionTypesByExternalIdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[56] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypesByExternalIdsRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionTypesByExternalIdsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{56} +} + +func (x *GetExecutionTypesByExternalIdsRequest) GetExternalIds() []string { + if x != nil { + return x.ExternalIds + } + return nil +} + +func (x *GetExecutionTypesByExternalIdsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionTypesByExternalIdsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionTypes []*ExecutionType `protobuf:"bytes,1,rep,name=execution_types,json=executionTypes" json:"execution_types,omitempty"` +} + +func (x *GetExecutionTypesByExternalIdsResponse) Reset() { + *x = GetExecutionTypesByExternalIdsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypesByExternalIdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypesByExternalIdsResponse) ProtoMessage() {} + +func (x *GetExecutionTypesByExternalIdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[57] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypesByExternalIdsResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionTypesByExternalIdsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{57} +} + +func (x *GetExecutionTypesByExternalIdsResponse) GetExecutionTypes() []*ExecutionType { + if x != nil { + return x.ExecutionTypes + } + return nil +} + +type GetContextTypesByExternalIdsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExternalIds []string `protobuf:"bytes,1,rep,name=external_ids,json=externalIds" json:"external_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextTypesByExternalIdsRequest) Reset() { + *x = GetContextTypesByExternalIdsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[58] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypesByExternalIdsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypesByExternalIdsRequest) ProtoMessage() {} + +func (x *GetContextTypesByExternalIdsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[58] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypesByExternalIdsRequest.ProtoReflect.Descriptor instead. +func (*GetContextTypesByExternalIdsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{58} +} + +func (x *GetContextTypesByExternalIdsRequest) GetExternalIds() []string { + if x != nil { + return x.ExternalIds + } + return nil +} + +func (x *GetContextTypesByExternalIdsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextTypesByExternalIdsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextTypes []*ContextType `protobuf:"bytes,1,rep,name=context_types,json=contextTypes" json:"context_types,omitempty"` +} + +func (x *GetContextTypesByExternalIdsResponse) Reset() { + *x = GetContextTypesByExternalIdsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[59] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypesByExternalIdsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypesByExternalIdsResponse) ProtoMessage() {} + +func (x *GetContextTypesByExternalIdsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[59] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypesByExternalIdsResponse.ProtoReflect.Descriptor instead. +func (*GetContextTypesByExternalIdsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{59} +} + +func (x *GetContextTypesByExternalIdsResponse) GetContextTypes() []*ContextType { + if x != nil { + return x.ContextTypes + } + return nil +} + +type GetExecutionsByTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name with default type_version. + TypeVersion *string `protobuf:"bytes,2,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + // + // If set, the request will + // + // first fetch all executions with specified `type_name` and `type_version`, + // then order by a specifield field + // finally find the correct page and return #Executions of the page size. + // + // Higher-level APIs may only use the functionalies partially. + // Please reference the API documentation for the API behaviors. + Options *ListOperationOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,4,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionsByTypeRequest) Reset() { + *x = GetExecutionsByTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[60] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByTypeRequest) ProtoMessage() {} + +func (x *GetExecutionsByTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[60] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByTypeRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionsByTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{60} +} + +func (x *GetExecutionsByTypeRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetExecutionsByTypeRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetExecutionsByTypeRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetExecutionsByTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionsByTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Executions []*Execution `protobuf:"bytes,1,rep,name=executions" json:"executions,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (x *GetExecutionsByTypeResponse) Reset() { + *x = GetExecutionsByTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[61] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByTypeResponse) ProtoMessage() {} + +func (x *GetExecutionsByTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[61] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByTypeResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionsByTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{61} +} + +func (x *GetExecutionsByTypeResponse) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +func (x *GetExecutionsByTypeResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +type GetExecutionByTypeAndNameRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name and execution_name with + // default type_version. + TypeVersion *string `protobuf:"bytes,3,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + ExecutionName *string `protobuf:"bytes,2,opt,name=execution_name,json=executionName" json:"execution_name,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,4,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionByTypeAndNameRequest) Reset() { + *x = GetExecutionByTypeAndNameRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[62] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionByTypeAndNameRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionByTypeAndNameRequest) ProtoMessage() {} + +func (x *GetExecutionByTypeAndNameRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[62] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionByTypeAndNameRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionByTypeAndNameRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{62} +} + +func (x *GetExecutionByTypeAndNameRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetExecutionByTypeAndNameRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetExecutionByTypeAndNameRequest) GetExecutionName() string { + if x != nil && x.ExecutionName != nil { + return *x.ExecutionName + } + return "" +} + +func (x *GetExecutionByTypeAndNameRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionByTypeAndNameResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Execution *Execution `protobuf:"bytes,1,opt,name=execution" json:"execution,omitempty"` +} + +func (x *GetExecutionByTypeAndNameResponse) Reset() { + *x = GetExecutionByTypeAndNameResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[63] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionByTypeAndNameResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionByTypeAndNameResponse) ProtoMessage() {} + +func (x *GetExecutionByTypeAndNameResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[63] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionByTypeAndNameResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionByTypeAndNameResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{63} +} + +func (x *GetExecutionByTypeAndNameResponse) GetExecution() *Execution { + if x != nil { + return x.Execution + } + return nil +} + +type GetExecutionsByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of execution ids to retrieve. + ExecutionIds []int64 `protobuf:"varint,1,rep,name=execution_ids,json=executionIds" json:"execution_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionsByIDRequest) Reset() { + *x = GetExecutionsByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByIDRequest) ProtoMessage() {} + +func (x *GetExecutionsByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[64] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByIDRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionsByIDRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{64} +} + +func (x *GetExecutionsByIDRequest) GetExecutionIds() []int64 { + if x != nil { + return x.ExecutionIds + } + return nil +} + +func (x *GetExecutionsByIDRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionsByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The result is not index-aligned: if an id is not found, it is not + // returned. + Executions []*Execution `protobuf:"bytes,1,rep,name=executions" json:"executions,omitempty"` +} + +func (x *GetExecutionsByIDResponse) Reset() { + *x = GetExecutionsByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByIDResponse) ProtoMessage() {} + +func (x *GetExecutionsByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[65] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByIDResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionsByIDResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{65} +} + +func (x *GetExecutionsByIDResponse) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +type GetExecutionTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name with default type_version. + TypeVersion *string `protobuf:"bytes,2,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionTypeRequest) Reset() { + *x = GetExecutionTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[66] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypeRequest) ProtoMessage() {} + +func (x *GetExecutionTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[66] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypeRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{66} +} + +func (x *GetExecutionTypeRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetExecutionTypeRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetExecutionTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Gets an execution type, or clear if it does not exist. + ExecutionType *ExecutionType `protobuf:"bytes,1,opt,name=execution_type,json=executionType" json:"execution_type,omitempty"` +} + +func (x *GetExecutionTypeResponse) Reset() { + *x = GetExecutionTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[67] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypeResponse) ProtoMessage() {} + +func (x *GetExecutionTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[67] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypeResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{67} +} + +func (x *GetExecutionTypeResponse) GetExecutionType() *ExecutionType { + if x != nil { + return x.ExecutionType + } + return nil +} + +// Gets all events with matching execution ids. +type GetEventsByExecutionIDsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionIds []int64 `protobuf:"varint,1,rep,name=execution_ids,json=executionIds" json:"execution_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetEventsByExecutionIDsRequest) Reset() { + *x = GetEventsByExecutionIDsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[68] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEventsByExecutionIDsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEventsByExecutionIDsRequest) ProtoMessage() {} + +func (x *GetEventsByExecutionIDsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[68] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEventsByExecutionIDsRequest.ProtoReflect.Descriptor instead. +func (*GetEventsByExecutionIDsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{68} +} + +func (x *GetEventsByExecutionIDsRequest) GetExecutionIds() []int64 { + if x != nil { + return x.ExecutionIds + } + return nil +} + +func (x *GetEventsByExecutionIDsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetEventsByExecutionIDsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Events []*Event `protobuf:"bytes,1,rep,name=events" json:"events,omitempty"` +} + +func (x *GetEventsByExecutionIDsResponse) Reset() { + *x = GetEventsByExecutionIDsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[69] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEventsByExecutionIDsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEventsByExecutionIDsResponse) ProtoMessage() {} + +func (x *GetEventsByExecutionIDsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[69] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEventsByExecutionIDsResponse.ProtoReflect.Descriptor instead. +func (*GetEventsByExecutionIDsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{69} +} + +func (x *GetEventsByExecutionIDsResponse) GetEvents() []*Event { + if x != nil { + return x.Events + } + return nil +} + +type GetEventsByArtifactIDsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ArtifactIds []int64 `protobuf:"varint,1,rep,name=artifact_ids,json=artifactIds" json:"artifact_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetEventsByArtifactIDsRequest) Reset() { + *x = GetEventsByArtifactIDsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[70] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEventsByArtifactIDsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEventsByArtifactIDsRequest) ProtoMessage() {} + +func (x *GetEventsByArtifactIDsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[70] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEventsByArtifactIDsRequest.ProtoReflect.Descriptor instead. +func (*GetEventsByArtifactIDsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{70} +} + +func (x *GetEventsByArtifactIDsRequest) GetArtifactIds() []int64 { + if x != nil { + return x.ArtifactIds + } + return nil +} + +func (x *GetEventsByArtifactIDsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetEventsByArtifactIDsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Events []*Event `protobuf:"bytes,1,rep,name=events" json:"events,omitempty"` +} + +func (x *GetEventsByArtifactIDsResponse) Reset() { + *x = GetEventsByArtifactIDsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[71] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetEventsByArtifactIDsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetEventsByArtifactIDsResponse) ProtoMessage() {} + +func (x *GetEventsByArtifactIDsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[71] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetEventsByArtifactIDsResponse.ProtoReflect.Descriptor instead. +func (*GetEventsByArtifactIDsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{71} +} + +func (x *GetEventsByArtifactIDsResponse) GetEvents() []*Event { + if x != nil { + return x.Events + } + return nil +} + +type GetArtifactTypesByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeIds []int64 `protobuf:"varint,1,rep,name=type_ids,json=typeIds" json:"type_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactTypesByIDRequest) Reset() { + *x = GetArtifactTypesByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[72] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypesByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypesByIDRequest) ProtoMessage() {} + +func (x *GetArtifactTypesByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[72] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypesByIDRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactTypesByIDRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{72} +} + +func (x *GetArtifactTypesByIDRequest) GetTypeIds() []int64 { + if x != nil { + return x.TypeIds + } + return nil +} + +func (x *GetArtifactTypesByIDRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactTypesByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The result is not index-aligned: if an id is not found, it is not + // returned. + ArtifactTypes []*ArtifactType `protobuf:"bytes,1,rep,name=artifact_types,json=artifactTypes" json:"artifact_types,omitempty"` +} + +func (x *GetArtifactTypesByIDResponse) Reset() { + *x = GetArtifactTypesByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[73] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactTypesByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactTypesByIDResponse) ProtoMessage() {} + +func (x *GetArtifactTypesByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[73] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactTypesByIDResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactTypesByIDResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{73} +} + +func (x *GetArtifactTypesByIDResponse) GetArtifactTypes() []*ArtifactType { + if x != nil { + return x.ArtifactTypes + } + return nil +} + +type GetExecutionTypesByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeIds []int64 `protobuf:"varint,1,rep,name=type_ids,json=typeIds" json:"type_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionTypesByIDRequest) Reset() { + *x = GetExecutionTypesByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[74] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypesByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypesByIDRequest) ProtoMessage() {} + +func (x *GetExecutionTypesByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[74] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypesByIDRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionTypesByIDRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{74} +} + +func (x *GetExecutionTypesByIDRequest) GetTypeIds() []int64 { + if x != nil { + return x.TypeIds + } + return nil +} + +func (x *GetExecutionTypesByIDRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionTypesByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The result is not index-aligned: if an id is not found, it is not + // returned. + ExecutionTypes []*ExecutionType `protobuf:"bytes,1,rep,name=execution_types,json=executionTypes" json:"execution_types,omitempty"` +} + +func (x *GetExecutionTypesByIDResponse) Reset() { + *x = GetExecutionTypesByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[75] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionTypesByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionTypesByIDResponse) ProtoMessage() {} + +func (x *GetExecutionTypesByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[75] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionTypesByIDResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionTypesByIDResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{75} +} + +func (x *GetExecutionTypesByIDResponse) GetExecutionTypes() []*ExecutionType { + if x != nil { + return x.ExecutionTypes + } + return nil +} + +type GetContextTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name with default type_version. + TypeVersion *string `protobuf:"bytes,2,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextTypeRequest) Reset() { + *x = GetContextTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[76] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypeRequest) ProtoMessage() {} + +func (x *GetContextTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[76] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypeRequest.ProtoReflect.Descriptor instead. +func (*GetContextTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{76} +} + +func (x *GetContextTypeRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetContextTypeRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetContextTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Gets a context type, or clear if it does not exist. + ContextType *ContextType `protobuf:"bytes,1,opt,name=context_type,json=contextType" json:"context_type,omitempty"` +} + +func (x *GetContextTypeResponse) Reset() { + *x = GetContextTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[77] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypeResponse) ProtoMessage() {} + +func (x *GetContextTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[77] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypeResponse.ProtoReflect.Descriptor instead. +func (*GetContextTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{77} +} + +func (x *GetContextTypeResponse) GetContextType() *ContextType { + if x != nil { + return x.ContextType + } + return nil +} + +type GetContextTypesByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeIds []int64 `protobuf:"varint,1,rep,name=type_ids,json=typeIds" json:"type_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextTypesByIDRequest) Reset() { + *x = GetContextTypesByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[78] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypesByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypesByIDRequest) ProtoMessage() {} + +func (x *GetContextTypesByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[78] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypesByIDRequest.ProtoReflect.Descriptor instead. +func (*GetContextTypesByIDRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{78} +} + +func (x *GetContextTypesByIDRequest) GetTypeIds() []int64 { + if x != nil { + return x.TypeIds + } + return nil +} + +func (x *GetContextTypesByIDRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextTypesByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The result is not index-aligned: if an id is not found, it is not + // returned. + ContextTypes []*ContextType `protobuf:"bytes,1,rep,name=context_types,json=contextTypes" json:"context_types,omitempty"` +} + +func (x *GetContextTypesByIDResponse) Reset() { + *x = GetContextTypesByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[79] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextTypesByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextTypesByIDResponse) ProtoMessage() {} + +func (x *GetContextTypesByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[79] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextTypesByIDResponse.ProtoReflect.Descriptor instead. +func (*GetContextTypesByIDResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{79} +} + +func (x *GetContextTypesByIDResponse) GetContextTypes() []*ContextType { + if x != nil { + return x.ContextTypes + } + return nil +} + +// Request to retrieve Contexts using List options. +// If option is not specified then all Contexts are returned. +type GetContextsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Specify options. + // Please refer to the documentation of ListOperationOptions for the supported + // functionalities. + Options *ListOperationOptions `protobuf:"bytes,1,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextsRequest) Reset() { + *x = GetContextsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[80] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsRequest) ProtoMessage() {} + +func (x *GetContextsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[80] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsRequest.ProtoReflect.Descriptor instead. +func (*GetContextsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{80} +} + +func (x *GetContextsRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetContextsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Returned contexts. + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (x *GetContextsResponse) Reset() { + *x = GetContextsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[81] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsResponse) ProtoMessage() {} + +func (x *GetContextsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[81] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsResponse.ProtoReflect.Descriptor instead. +func (*GetContextsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{81} +} + +func (x *GetContextsResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +func (x *GetContextsResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +type GetContextsByTypeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // Specify options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + // + // If set, the request will + // + // first fetch all contexts with specified `type_name` and `type_version`, + // then order by a specifield field + // finally find the correct page and return #Contexts of the page size. + // + // Higher-level APIs may only use the functionalies partially. + // Please reference the API documentation for the API behaviors. + Options *ListOperationOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + // If not set, it looks for the type with type_name and options with default + // type_version. + TypeVersion *string `protobuf:"bytes,3,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,4,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextsByTypeRequest) Reset() { + *x = GetContextsByTypeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[82] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByTypeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByTypeRequest) ProtoMessage() {} + +func (x *GetContextsByTypeRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[82] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByTypeRequest.ProtoReflect.Descriptor instead. +func (*GetContextsByTypeRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{82} +} + +func (x *GetContextsByTypeRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetContextsByTypeRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetContextsByTypeRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetContextsByTypeRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextsByTypeResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (x *GetContextsByTypeResponse) Reset() { + *x = GetContextsByTypeResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[83] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByTypeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByTypeResponse) ProtoMessage() {} + +func (x *GetContextsByTypeResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[83] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByTypeResponse.ProtoReflect.Descriptor instead. +func (*GetContextsByTypeResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{83} +} + +func (x *GetContextsByTypeResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +func (x *GetContextsByTypeResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +type GetContextByTypeAndNameRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TypeName *string `protobuf:"bytes,1,opt,name=type_name,json=typeName" json:"type_name,omitempty"` + // If not set, it looks for the type with type_name and context_name with + // default type_version. + TypeVersion *string `protobuf:"bytes,3,opt,name=type_version,json=typeVersion" json:"type_version,omitempty"` + ContextName *string `protobuf:"bytes,2,opt,name=context_name,json=contextName" json:"context_name,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,4,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextByTypeAndNameRequest) Reset() { + *x = GetContextByTypeAndNameRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[84] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextByTypeAndNameRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextByTypeAndNameRequest) ProtoMessage() {} + +func (x *GetContextByTypeAndNameRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[84] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextByTypeAndNameRequest.ProtoReflect.Descriptor instead. +func (*GetContextByTypeAndNameRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{84} +} + +func (x *GetContextByTypeAndNameRequest) GetTypeName() string { + if x != nil && x.TypeName != nil { + return *x.TypeName + } + return "" +} + +func (x *GetContextByTypeAndNameRequest) GetTypeVersion() string { + if x != nil && x.TypeVersion != nil { + return *x.TypeVersion + } + return "" +} + +func (x *GetContextByTypeAndNameRequest) GetContextName() string { + if x != nil && x.ContextName != nil { + return *x.ContextName + } + return "" +} + +func (x *GetContextByTypeAndNameRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextByTypeAndNameResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Context *Context `protobuf:"bytes,1,opt,name=context" json:"context,omitempty"` +} + +func (x *GetContextByTypeAndNameResponse) Reset() { + *x = GetContextByTypeAndNameResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[85] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextByTypeAndNameResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextByTypeAndNameResponse) ProtoMessage() {} + +func (x *GetContextByTypeAndNameResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[85] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextByTypeAndNameResponse.ProtoReflect.Descriptor instead. +func (*GetContextByTypeAndNameResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{85} +} + +func (x *GetContextByTypeAndNameResponse) GetContext() *Context { + if x != nil { + return x.Context + } + return nil +} + +type GetContextsByIDRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A list of context ids to retrieve. + ContextIds []int64 `protobuf:"varint,1,rep,name=context_ids,json=contextIds" json:"context_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextsByIDRequest) Reset() { + *x = GetContextsByIDRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[86] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByIDRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByIDRequest) ProtoMessage() {} + +func (x *GetContextsByIDRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[86] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByIDRequest.ProtoReflect.Descriptor instead. +func (*GetContextsByIDRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{86} +} + +func (x *GetContextsByIDRequest) GetContextIds() []int64 { + if x != nil { + return x.ContextIds + } + return nil +} + +func (x *GetContextsByIDRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextsByIDResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The result is not index-aligned: if an id is not found, it is not + // returned. + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` +} + +func (x *GetContextsByIDResponse) Reset() { + *x = GetContextsByIDResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[87] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByIDResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByIDResponse) ProtoMessage() {} + +func (x *GetContextsByIDResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[87] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByIDResponse.ProtoReflect.Descriptor instead. +func (*GetContextsByIDResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{87} +} + +func (x *GetContextsByIDResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +type GetContextsByArtifactRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ArtifactId *int64 `protobuf:"varint,1,opt,name=artifact_id,json=artifactId" json:"artifact_id,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextsByArtifactRequest) Reset() { + *x = GetContextsByArtifactRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[88] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByArtifactRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByArtifactRequest) ProtoMessage() {} + +func (x *GetContextsByArtifactRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[88] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByArtifactRequest.ProtoReflect.Descriptor instead. +func (*GetContextsByArtifactRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{88} +} + +func (x *GetContextsByArtifactRequest) GetArtifactId() int64 { + if x != nil && x.ArtifactId != nil { + return *x.ArtifactId + } + return 0 +} + +func (x *GetContextsByArtifactRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextsByArtifactResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` +} + +func (x *GetContextsByArtifactResponse) Reset() { + *x = GetContextsByArtifactResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[89] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByArtifactResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByArtifactResponse) ProtoMessage() {} + +func (x *GetContextsByArtifactResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[89] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByArtifactResponse.ProtoReflect.Descriptor instead. +func (*GetContextsByArtifactResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{89} +} + +func (x *GetContextsByArtifactResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +type GetContextsByExecutionRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId *int64 `protobuf:"varint,1,opt,name=execution_id,json=executionId" json:"execution_id,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetContextsByExecutionRequest) Reset() { + *x = GetContextsByExecutionRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[90] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByExecutionRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByExecutionRequest) ProtoMessage() {} + +func (x *GetContextsByExecutionRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[90] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByExecutionRequest.ProtoReflect.Descriptor instead. +func (*GetContextsByExecutionRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{90} +} + +func (x *GetContextsByExecutionRequest) GetExecutionId() int64 { + if x != nil && x.ExecutionId != nil { + return *x.ExecutionId + } + return 0 +} + +func (x *GetContextsByExecutionRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetContextsByExecutionResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` +} + +func (x *GetContextsByExecutionResponse) Reset() { + *x = GetContextsByExecutionResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[91] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetContextsByExecutionResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetContextsByExecutionResponse) ProtoMessage() {} + +func (x *GetContextsByExecutionResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[91] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetContextsByExecutionResponse.ProtoReflect.Descriptor instead. +func (*GetContextsByExecutionResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{91} +} + +func (x *GetContextsByExecutionResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +type GetParentContextsByContextRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextId *int64 `protobuf:"varint,1,opt,name=context_id,json=contextId" json:"context_id,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetParentContextsByContextRequest) Reset() { + *x = GetParentContextsByContextRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[92] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetParentContextsByContextRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetParentContextsByContextRequest) ProtoMessage() {} + +func (x *GetParentContextsByContextRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[92] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetParentContextsByContextRequest.ProtoReflect.Descriptor instead. +func (*GetParentContextsByContextRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{92} +} + +func (x *GetParentContextsByContextRequest) GetContextId() int64 { + if x != nil && x.ContextId != nil { + return *x.ContextId + } + return 0 +} + +func (x *GetParentContextsByContextRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetParentContextsByContextResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` +} + +func (x *GetParentContextsByContextResponse) Reset() { + *x = GetParentContextsByContextResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[93] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetParentContextsByContextResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetParentContextsByContextResponse) ProtoMessage() {} + +func (x *GetParentContextsByContextResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[93] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetParentContextsByContextResponse.ProtoReflect.Descriptor instead. +func (*GetParentContextsByContextResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{93} +} + +func (x *GetParentContextsByContextResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +type GetChildrenContextsByContextRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextId *int64 `protobuf:"varint,1,opt,name=context_id,json=contextId" json:"context_id,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetChildrenContextsByContextRequest) Reset() { + *x = GetChildrenContextsByContextRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[94] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetChildrenContextsByContextRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetChildrenContextsByContextRequest) ProtoMessage() {} + +func (x *GetChildrenContextsByContextRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[94] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetChildrenContextsByContextRequest.ProtoReflect.Descriptor instead. +func (*GetChildrenContextsByContextRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{94} +} + +func (x *GetChildrenContextsByContextRequest) GetContextId() int64 { + if x != nil && x.ContextId != nil { + return *x.ContextId + } + return 0 +} + +func (x *GetChildrenContextsByContextRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetChildrenContextsByContextResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts []*Context `protobuf:"bytes,1,rep,name=contexts" json:"contexts,omitempty"` +} + +func (x *GetChildrenContextsByContextResponse) Reset() { + *x = GetChildrenContextsByContextResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[95] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetChildrenContextsByContextResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetChildrenContextsByContextResponse) ProtoMessage() {} + +func (x *GetChildrenContextsByContextResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[95] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetChildrenContextsByContextResponse.ProtoReflect.Descriptor instead. +func (*GetChildrenContextsByContextResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{95} +} + +func (x *GetChildrenContextsByContextResponse) GetContexts() []*Context { + if x != nil { + return x.Contexts + } + return nil +} + +type GetParentContextsByContextsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextIds []int64 `protobuf:"varint,1,rep,packed,name=context_ids,json=contextIds" json:"context_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetParentContextsByContextsRequest) Reset() { + *x = GetParentContextsByContextsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[96] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetParentContextsByContextsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetParentContextsByContextsRequest) ProtoMessage() {} + +func (x *GetParentContextsByContextsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[96] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetParentContextsByContextsRequest.ProtoReflect.Descriptor instead. +func (*GetParentContextsByContextsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{96} +} + +func (x *GetParentContextsByContextsRequest) GetContextIds() []int64 { + if x != nil { + return x.ContextIds + } + return nil +} + +func (x *GetParentContextsByContextsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetParentContextsByContextsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts map[int64]*GetParentContextsByContextsResponse_ParentContextsPerChild `protobuf:"bytes,2,rep,name=contexts" json:"contexts,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (x *GetParentContextsByContextsResponse) Reset() { + *x = GetParentContextsByContextsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[97] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetParentContextsByContextsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetParentContextsByContextsResponse) ProtoMessage() {} + +func (x *GetParentContextsByContextsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[97] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetParentContextsByContextsResponse.ProtoReflect.Descriptor instead. +func (*GetParentContextsByContextsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{97} +} + +func (x *GetParentContextsByContextsResponse) GetContexts() map[int64]*GetParentContextsByContextsResponse_ParentContextsPerChild { + if x != nil { + return x.Contexts + } + return nil +} + +type GetChildrenContextsByContextsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextIds []int64 `protobuf:"varint,1,rep,packed,name=context_ids,json=contextIds" json:"context_ids,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetChildrenContextsByContextsRequest) Reset() { + *x = GetChildrenContextsByContextsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[98] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetChildrenContextsByContextsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetChildrenContextsByContextsRequest) ProtoMessage() {} + +func (x *GetChildrenContextsByContextsRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[98] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetChildrenContextsByContextsRequest.ProtoReflect.Descriptor instead. +func (*GetChildrenContextsByContextsRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{98} +} + +func (x *GetChildrenContextsByContextsRequest) GetContextIds() []int64 { + if x != nil { + return x.ContextIds + } + return nil +} + +func (x *GetChildrenContextsByContextsRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetChildrenContextsByContextsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Contexts map[int64]*GetChildrenContextsByContextsResponse_ChildrenContextsPerParent `protobuf:"bytes,2,rep,name=contexts" json:"contexts,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (x *GetChildrenContextsByContextsResponse) Reset() { + *x = GetChildrenContextsByContextsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[99] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetChildrenContextsByContextsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetChildrenContextsByContextsResponse) ProtoMessage() {} + +func (x *GetChildrenContextsByContextsResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[99] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetChildrenContextsByContextsResponse.ProtoReflect.Descriptor instead. +func (*GetChildrenContextsByContextsResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{99} +} + +func (x *GetChildrenContextsByContextsResponse) GetContexts() map[int64]*GetChildrenContextsByContextsResponse_ChildrenContextsPerParent { + if x != nil { + return x.Contexts + } + return nil +} + +type GetArtifactsByContextRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextId *int64 `protobuf:"varint,1,opt,name=context_id,json=contextId" json:"context_id,omitempty"` + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + Options *ListOperationOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetArtifactsByContextRequest) Reset() { + *x = GetArtifactsByContextRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[100] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByContextRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByContextRequest) ProtoMessage() {} + +func (x *GetArtifactsByContextRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[100] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByContextRequest.ProtoReflect.Descriptor instead. +func (*GetArtifactsByContextRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{100} +} + +func (x *GetArtifactsByContextRequest) GetContextId() int64 { + if x != nil && x.ContextId != nil { + return *x.ContextId + } + return 0 +} + +func (x *GetArtifactsByContextRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetArtifactsByContextRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetArtifactsByContextResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Artifacts []*Artifact `protobuf:"bytes,1,rep,name=artifacts" json:"artifacts,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` +} + +func (x *GetArtifactsByContextResponse) Reset() { + *x = GetArtifactsByContextResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[101] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetArtifactsByContextResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetArtifactsByContextResponse) ProtoMessage() {} + +func (x *GetArtifactsByContextResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[101] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetArtifactsByContextResponse.ProtoReflect.Descriptor instead. +func (*GetArtifactsByContextResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{101} +} + +func (x *GetArtifactsByContextResponse) GetArtifacts() []*Artifact { + if x != nil { + return x.Artifacts + } + return nil +} + +func (x *GetArtifactsByContextResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +type GetExecutionsByContextRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ContextId *int64 `protobuf:"varint,1,opt,name=context_id,json=contextId" json:"context_id,omitempty"` + // Specify List options. + // Currently supports: + // 1. Field to order the results. + // 2. Page size. + Options *ListOperationOptions `protobuf:"bytes,2,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionsByContextRequest) Reset() { + *x = GetExecutionsByContextRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[102] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByContextRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByContextRequest) ProtoMessage() {} + +func (x *GetExecutionsByContextRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[102] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByContextRequest.ProtoReflect.Descriptor instead. +func (*GetExecutionsByContextRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{102} +} + +func (x *GetExecutionsByContextRequest) GetContextId() int64 { + if x != nil && x.ContextId != nil { + return *x.ContextId + } + return 0 +} + +func (x *GetExecutionsByContextRequest) GetOptions() *ListOperationOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetExecutionsByContextRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetExecutionsByContextResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Executions []*Execution `protobuf:"bytes,1,rep,name=executions" json:"executions,omitempty"` + // Token to use to retrieve next page of results if list options are used in + // the request. + NextPageToken *string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken" json:"next_page_token,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,3,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetExecutionsByContextResponse) Reset() { + *x = GetExecutionsByContextResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[103] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetExecutionsByContextResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetExecutionsByContextResponse) ProtoMessage() {} + +func (x *GetExecutionsByContextResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[103] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetExecutionsByContextResponse.ProtoReflect.Descriptor instead. +func (*GetExecutionsByContextResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{103} +} + +func (x *GetExecutionsByContextResponse) GetExecutions() []*Execution { + if x != nil { + return x.Executions + } + return nil +} + +func (x *GetExecutionsByContextResponse) GetNextPageToken() string { + if x != nil && x.NextPageToken != nil { + return *x.NextPageToken + } + return "" +} + +func (x *GetExecutionsByContextResponse) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +// TODO(b/283852485): Deprecate GetLineageGraph API after migration to +// GetLineageSubgraph API. +// A lineage query request to specify the query nodes of interest and the +// boundary conditions for pruning the returned graph. +type GetLineageGraphRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Options *LineageGraphQueryOptions `protobuf:"bytes,1,opt,name=options" json:"options,omitempty"` + // Options regarding transactions. + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetLineageGraphRequest) Reset() { + *x = GetLineageGraphRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[104] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLineageGraphRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLineageGraphRequest) ProtoMessage() {} + +func (x *GetLineageGraphRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[104] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLineageGraphRequest.ProtoReflect.Descriptor instead. +func (*GetLineageGraphRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{104} +} + +func (x *GetLineageGraphRequest) GetOptions() *LineageGraphQueryOptions { + if x != nil { + return x.Options + } + return nil +} + +func (x *GetLineageGraphRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +// A connected lineage `subgraph` about the MLMD nodes derived from +// LineageGraphRequest.query_conditions. +type GetLineageGraphResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Subgraph *LineageGraph `protobuf:"bytes,1,opt,name=subgraph" json:"subgraph,omitempty"` +} + +func (x *GetLineageGraphResponse) Reset() { + *x = GetLineageGraphResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[105] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLineageGraphResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLineageGraphResponse) ProtoMessage() {} + +func (x *GetLineageGraphResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[105] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLineageGraphResponse.ProtoReflect.Descriptor instead. +func (*GetLineageGraphResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{105} +} + +func (x *GetLineageGraphResponse) GetSubgraph() *LineageGraph { + if x != nil { + return x.Subgraph + } + return nil +} + +type GetLineageSubgraphRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Query options for lineage graph tracing from a list of interested + // nodes. + // A lineage subgraph without node details (e.g., external_id, properties) + // will be returned. Please refer to `LineageSubgraphQueryOptions` for more + // details. + LineageSubgraphQueryOptions *LineageSubgraphQueryOptions `protobuf:"bytes,1,opt,name=lineage_subgraph_query_options,json=lineageSubgraphQueryOptions" json:"lineage_subgraph_query_options,omitempty"` + // `read_mask` contains user specified paths of fields that should be included + // in the returned lineage subgraph. + // + // Supported field paths are: 'artifacts', 'executions', 'contexts', + // 'artifact_types', 'execution_types', 'context_types', and 'events'. + // TODO(b/283852485): Include 'associations' or 'attributions' in the + // returned graph. + // If 'artifacts', 'executions', or 'contexts' is specified in `read_mask`, + // the dehydrated nodes will be included. + // Note: A dehydrated node means a node containing only its id and no + // other information. User should call GetNodesByID or other APIs to get + // node details later on. + // If 'artifact_types', 'execution_types', or 'context_types' is specified + // in `read_mask`, all the node types will be included. + // If 'events' is specified in `read_mask`, the events will be included. + // If `read_mask` is not set, the API will return all the fields in + // the returned graph. + // Note: Only paths of fields in LineageGraph message are supported. Paths + // of fields in the submessage, such as "artifacts.id", "contexts.name" are + // not acknowledged. + ReadMask *fieldmaskpb.FieldMask `protobuf:"bytes,3,opt,name=read_mask,json=readMask" json:"read_mask,omitempty"` + TransactionOptions *TransactionOptions `protobuf:"bytes,2,opt,name=transaction_options,json=transactionOptions" json:"transaction_options,omitempty"` +} + +func (x *GetLineageSubgraphRequest) Reset() { + *x = GetLineageSubgraphRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[106] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLineageSubgraphRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLineageSubgraphRequest) ProtoMessage() {} + +func (x *GetLineageSubgraphRequest) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[106] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLineageSubgraphRequest.ProtoReflect.Descriptor instead. +func (*GetLineageSubgraphRequest) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{106} +} + +func (x *GetLineageSubgraphRequest) GetLineageSubgraphQueryOptions() *LineageSubgraphQueryOptions { + if x != nil { + return x.LineageSubgraphQueryOptions + } + return nil +} + +func (x *GetLineageSubgraphRequest) GetReadMask() *fieldmaskpb.FieldMask { + if x != nil { + return x.ReadMask + } + return nil +} + +func (x *GetLineageSubgraphRequest) GetTransactionOptions() *TransactionOptions { + if x != nil { + return x.TransactionOptions + } + return nil +} + +type GetLineageSubgraphResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // A lineage subgraph of MLMD nodes and relations retrieved from lineage + // graph tracing. + LineageSubgraph *LineageGraph `protobuf:"bytes,1,opt,name=lineage_subgraph,json=lineageSubgraph" json:"lineage_subgraph,omitempty"` +} + +func (x *GetLineageSubgraphResponse) Reset() { + *x = GetLineageSubgraphResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[107] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetLineageSubgraphResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetLineageSubgraphResponse) ProtoMessage() {} + +func (x *GetLineageSubgraphResponse) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[107] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetLineageSubgraphResponse.ProtoReflect.Descriptor instead. +func (*GetLineageSubgraphResponse) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{107} +} + +func (x *GetLineageSubgraphResponse) GetLineageSubgraph() *LineageGraph { + if x != nil { + return x.LineageSubgraph + } + return nil +} + +type PutArtifactsRequest_Options struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // When there are multiple writers to update an existing node to + // different states, there may be a race and the end result of the + // concurrent update is nondeterministic. If the field is set, then an + // optimistic concurrency control (OCC) scheme is used during update: + // it compares the `artifact`.`last_update_time_since_epoch` in the request + // with the stored `last_update_time_since_epoch` having the same + // `artifact`.`id`. If they are different, the request fails, and the user + // can read the stored node and retry node update. + // When the option is set, the timestamp after update is guaranteed to be + // increased and different from the input artifact. + // When set the option, the caller should set it for all concurrent writers. + AbortIfLatestUpdatedTimeChanged *bool `protobuf:"varint,1,opt,name=abort_if_latest_updated_time_changed,json=abortIfLatestUpdatedTimeChanged" json:"abort_if_latest_updated_time_changed,omitempty"` +} + +func (x *PutArtifactsRequest_Options) Reset() { + *x = PutArtifactsRequest_Options{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[109] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutArtifactsRequest_Options) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutArtifactsRequest_Options) ProtoMessage() {} + +func (x *PutArtifactsRequest_Options) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[109] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutArtifactsRequest_Options.ProtoReflect.Descriptor instead. +func (*PutArtifactsRequest_Options) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *PutArtifactsRequest_Options) GetAbortIfLatestUpdatedTimeChanged() bool { + if x != nil && x.AbortIfLatestUpdatedTimeChanged != nil { + return *x.AbortIfLatestUpdatedTimeChanged + } + return false +} + +// A pair of an artifact and an event used or generated by an execution, e.g., +// during the execution run, it uses none or many artifacts as input, and +// generate none or many artifacts as output. +type PutExecutionRequest_ArtifactAndEvent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The pair may have an artifact. If present and no artifact.id is given, + // then it inserts the artifact, otherwise it updates the artifact. + Artifact *Artifact `protobuf:"bytes,1,opt,name=artifact" json:"artifact,omitempty"` + // The pair may have an event. Providing event.artifact_id or + // event.execution_id is optional. If the ids are given, it must align with + // the `artifact`.id / `execution`.id respectively. If artifact is not + // given and event.artifact_id is set, it must exist in the backend. + Event *Event `protobuf:"bytes,2,opt,name=event" json:"event,omitempty"` +} + +func (x *PutExecutionRequest_ArtifactAndEvent) Reset() { + *x = PutExecutionRequest_ArtifactAndEvent{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[110] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionRequest_ArtifactAndEvent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionRequest_ArtifactAndEvent) ProtoMessage() {} + +func (x *PutExecutionRequest_ArtifactAndEvent) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[110] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionRequest_ArtifactAndEvent.ProtoReflect.Descriptor instead. +func (*PutExecutionRequest_ArtifactAndEvent) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{14, 0} +} + +func (x *PutExecutionRequest_ArtifactAndEvent) GetArtifact() *Artifact { + if x != nil { + return x.Artifact + } + return nil +} + +func (x *PutExecutionRequest_ArtifactAndEvent) GetEvent() *Event { + if x != nil { + return x.Event + } + return nil +} + +type PutExecutionRequest_Options struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // When there's a race to publish executions with a new context with the + // same context.name, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. If set to true, + // the API will reuse the stored context in the transaction and perform + // an update. + ReuseContextIfAlreadyExist *bool `protobuf:"varint,1,opt,name=reuse_context_if_already_exist,json=reuseContextIfAlreadyExist" json:"reuse_context_if_already_exist,omitempty"` + // When there's a race to publish executions with a new artifact with the + // same artifact.external_id, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. + // If set to true and an Artifact has non-empty external_id, + // the API will reuse the stored artifact in the transaction and + // perform an update. Otherwise, it will fall back to relying on `id` field + // to decide if it's update (if `id` exists) or insert (if `id` is empty). + ReuseArtifactIfAlreadyExistByExternalId *bool `protobuf:"varint,2,opt,name=reuse_artifact_if_already_exist_by_external_id,json=reuseArtifactIfAlreadyExistByExternalId" json:"reuse_artifact_if_already_exist_by_external_id,omitempty"` +} + +func (x *PutExecutionRequest_Options) Reset() { + *x = PutExecutionRequest_Options{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[111] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutExecutionRequest_Options) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutExecutionRequest_Options) ProtoMessage() {} + +func (x *PutExecutionRequest_Options) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[111] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutExecutionRequest_Options.ProtoReflect.Descriptor instead. +func (*PutExecutionRequest_Options) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{14, 1} +} + +func (x *PutExecutionRequest_Options) GetReuseContextIfAlreadyExist() bool { + if x != nil && x.ReuseContextIfAlreadyExist != nil { + return *x.ReuseContextIfAlreadyExist + } + return false +} + +func (x *PutExecutionRequest_Options) GetReuseArtifactIfAlreadyExistByExternalId() bool { + if x != nil && x.ReuseArtifactIfAlreadyExistByExternalId != nil { + return *x.ReuseArtifactIfAlreadyExistByExternalId + } + return false +} + +type PutLineageSubgraphRequest_EventEdge struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Index in the array of executions. + ExecutionIndex *int32 `protobuf:"varint,1,opt,name=execution_index,json=executionIndex" json:"execution_index,omitempty"` + // Index in the array of artifacts. + ArtifactIndex *int32 `protobuf:"varint,2,opt,name=artifact_index,json=artifactIndex" json:"artifact_index,omitempty"` + Event *Event `protobuf:"bytes,3,opt,name=event" json:"event,omitempty"` +} + +func (x *PutLineageSubgraphRequest_EventEdge) Reset() { + *x = PutLineageSubgraphRequest_EventEdge{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[112] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutLineageSubgraphRequest_EventEdge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutLineageSubgraphRequest_EventEdge) ProtoMessage() {} + +func (x *PutLineageSubgraphRequest_EventEdge) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[112] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutLineageSubgraphRequest_EventEdge.ProtoReflect.Descriptor instead. +func (*PutLineageSubgraphRequest_EventEdge) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{16, 0} +} + +func (x *PutLineageSubgraphRequest_EventEdge) GetExecutionIndex() int32 { + if x != nil && x.ExecutionIndex != nil { + return *x.ExecutionIndex + } + return 0 +} + +func (x *PutLineageSubgraphRequest_EventEdge) GetArtifactIndex() int32 { + if x != nil && x.ArtifactIndex != nil { + return *x.ArtifactIndex + } + return 0 +} + +func (x *PutLineageSubgraphRequest_EventEdge) GetEvent() *Event { + if x != nil { + return x.Event + } + return nil +} + +type PutLineageSubgraphRequest_Options struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // When there's a race to publish executions with a new context with the + // same context.name, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. If set to true, + // the API will reuse the stored context in the transaction and perform + // an update. + ReuseContextIfAlreadyExist *bool `protobuf:"varint,1,opt,name=reuse_context_if_already_exist,json=reuseContextIfAlreadyExist" json:"reuse_context_if_already_exist,omitempty"` + // When there's a race to publish executions with a new artifact with the + // same artifact.external_id, by default there'll be one writer succeeds and + // the rest of the writers returning AlreadyExists errors. + // If set to true and an Artifact has non-empty external_id, + // the API will reuse the stored artifact in the transaction and + // perform an update. Otherwise, it will fall back to relying on `id` field + // to decide if it's update (if `id` exists) or insert (if `id` is empty). + ReuseArtifactIfAlreadyExistByExternalId *bool `protobuf:"varint,2,opt,name=reuse_artifact_if_already_exist_by_external_id,json=reuseArtifactIfAlreadyExistByExternalId" json:"reuse_artifact_if_already_exist_by_external_id,omitempty"` +} + +func (x *PutLineageSubgraphRequest_Options) Reset() { + *x = PutLineageSubgraphRequest_Options{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[113] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PutLineageSubgraphRequest_Options) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PutLineageSubgraphRequest_Options) ProtoMessage() {} + +func (x *PutLineageSubgraphRequest_Options) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[113] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PutLineageSubgraphRequest_Options.ProtoReflect.Descriptor instead. +func (*PutLineageSubgraphRequest_Options) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{16, 1} +} + +func (x *PutLineageSubgraphRequest_Options) GetReuseContextIfAlreadyExist() bool { + if x != nil && x.ReuseContextIfAlreadyExist != nil { + return *x.ReuseContextIfAlreadyExist + } + return false +} + +func (x *PutLineageSubgraphRequest_Options) GetReuseArtifactIfAlreadyExistByExternalId() bool { + if x != nil && x.ReuseArtifactIfAlreadyExistByExternalId != nil { + return *x.ReuseArtifactIfAlreadyExistByExternalId + } + return false +} + +type GetParentContextsByContextsResponse_ParentContextsPerChild struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ParentContexts []*Context `protobuf:"bytes,1,rep,name=parent_contexts,json=parentContexts" json:"parent_contexts,omitempty"` +} + +func (x *GetParentContextsByContextsResponse_ParentContextsPerChild) Reset() { + *x = GetParentContextsByContextsResponse_ParentContextsPerChild{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[114] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetParentContextsByContextsResponse_ParentContextsPerChild) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetParentContextsByContextsResponse_ParentContextsPerChild) ProtoMessage() {} + +func (x *GetParentContextsByContextsResponse_ParentContextsPerChild) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[114] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetParentContextsByContextsResponse_ParentContextsPerChild.ProtoReflect.Descriptor instead. +func (*GetParentContextsByContextsResponse_ParentContextsPerChild) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{97, 0} +} + +func (x *GetParentContextsByContextsResponse_ParentContextsPerChild) GetParentContexts() []*Context { + if x != nil { + return x.ParentContexts + } + return nil +} + +type GetChildrenContextsByContextsResponse_ChildrenContextsPerParent struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ChildrenContexts []*Context `protobuf:"bytes,1,rep,name=children_contexts,json=childrenContexts" json:"children_contexts,omitempty"` +} + +func (x *GetChildrenContextsByContextsResponse_ChildrenContextsPerParent) Reset() { + *x = GetChildrenContextsByContextsResponse_ChildrenContextsPerParent{} + if protoimpl.UnsafeEnabled { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[116] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetChildrenContextsByContextsResponse_ChildrenContextsPerParent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetChildrenContextsByContextsResponse_ChildrenContextsPerParent) ProtoMessage() {} + +func (x *GetChildrenContextsByContextsResponse_ChildrenContextsPerParent) ProtoReflect() protoreflect.Message { + mi := &file_ml_metadata_proto_metadata_store_service_proto_msgTypes[116] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetChildrenContextsByContextsResponse_ChildrenContextsPerParent.ProtoReflect.Descriptor instead. +func (*GetChildrenContextsByContextsResponse_ChildrenContextsPerParent) Descriptor() ([]byte, []int) { + return file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP(), []int{99, 0} +} + +func (x *GetChildrenContextsByContextsResponse_ChildrenContextsPerParent) GetChildrenContexts() []*Context { + if x != nil { + return x.ChildrenContexts + } + return nil +} + +var File_ml_metadata_proto_metadata_store_service_proto protoreflect.FileDescriptor + +var file_ml_metadata_proto_metadata_store_service_proto_rawDesc = []byte{ + 0x0a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x74, 0x6f, + 0x72, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x12, 0x0b, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x20, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, + 0x26, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x73, 0x0a, 0x0f, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x41, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x61, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x2d, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xbf, 0x01, 0x0a, + 0x11, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4d, + 0x61, 0x70, 0x12, 0x4e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, + 0x65, 0x73, 0x1a, 0x5a, 0x0a, 0x0f, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x31, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x4d, + 0x0a, 0x12, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x52, 0x08, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xc0, 0x01, + 0x0a, 0x0e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, + 0x12, 0x3a, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, + 0x48, 0x00, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x32, 0x0a, 0x03, + 0x6d, 0x61, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x48, 0x00, 0x52, 0x03, 0x6d, 0x61, 0x70, + 0x12, 0x35, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x48, + 0x00, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0xf7, 0x02, 0x0a, 0x13, 0x50, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x42, 0x0a, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, + 0x73, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, + 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, + 0x1a, 0x58, 0x0a, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4d, 0x0a, 0x24, 0x61, + 0x62, 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x66, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x6e, + 0x67, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1f, 0x61, 0x62, 0x6f, 0x72, 0x74, + 0x49, 0x66, 0x4c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x64, 0x22, 0x39, 0x0a, 0x14, 0x50, 0x75, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x49, 0x64, 0x73, 0x22, 0xdc, 0x02, 0x0a, 0x16, 0x50, 0x75, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x3e, 0x0a, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, 0x61, 0x6e, 0x41, 0x64, 0x64, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x63, 0x61, 0x6e, 0x5f, 0x6f, 0x6d, + 0x69, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0d, 0x63, 0x61, 0x6e, 0x4f, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2e, + 0x0a, 0x11, 0x63, 0x61, 0x6e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x63, + 0x61, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x32, + 0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x5f, 0x6d, 0x61, 0x74, + 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x32, 0x0a, 0x17, 0x50, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x17, 0x0a, 0x07, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x06, 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, 0x22, 0xdd, 0x01, 0x0a, 0x14, 0x50, 0x75, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x36, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x3c, 0x0a, 0x15, 0x50, 0x75, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x17, 0x50, 0x75, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x41, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, + 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, + 0x61, 0x6e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x63, + 0x61, 0x6e, 0x5f, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x63, 0x61, 0x6e, 0x4f, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x11, 0x63, 0x61, 0x6e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, + 0x72, 0x75, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x33, 0x0a, 0x18, 0x50, 0x75, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, 0x22, 0x90, + 0x01, 0x0a, 0x10, 0x50, 0x75, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x13, 0x0a, 0x11, 0x50, 0x75, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x9a, 0x05, 0x0a, 0x13, 0x50, 0x75, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, + 0x0a, 0x09, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x63, 0x0a, 0x14, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x69, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x6e, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x12, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x69, 0x72, 0x73, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x42, 0x0a, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x1a, 0x6f, 0x0a, 0x10, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x41, 0x6e, 0x64, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x08, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x28, 0x0a, 0x05, 0x65, 0x76, 0x65, 0x6e, + 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x1a, 0xae, 0x01, 0x0a, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x42, + 0x0a, 0x1e, 0x72, 0x65, 0x75, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, + 0x69, 0x66, 0x5f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x75, 0x73, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x66, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, + 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x2e, 0x72, 0x65, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x66, 0x5f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x5f, 0x62, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, 0x72, 0x65, 0x75, 0x73, + 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x66, 0x41, 0x6c, 0x72, 0x65, 0x61, + 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x49, 0x64, 0x22, 0x7d, 0x0a, 0x14, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x21, + 0x0a, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x03, 0x52, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, + 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x73, + 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, + 0x64, 0x73, 0x22, 0xe2, 0x05, 0x0a, 0x19, 0x50, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, + 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x36, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x33, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x30, 0x0a, + 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, + 0x51, 0x0a, 0x0b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x65, 0x64, 0x67, 0x65, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, + 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x45, 0x64, 0x67, 0x65, 0x52, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x45, 0x64, 0x67, + 0x65, 0x73, 0x12, 0x48, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x85, + 0x01, 0x0a, 0x09, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x45, 0x64, 0x67, 0x65, 0x12, 0x27, 0x0a, 0x0f, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x28, 0x0a, 0x05, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, + 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x1a, 0xae, 0x01, 0x0a, 0x07, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x42, 0x0a, 0x1e, 0x72, 0x65, 0x75, 0x73, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x5f, 0x69, 0x66, 0x5f, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x65, + 0x78, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x1a, 0x72, 0x65, 0x75, 0x73, + 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x66, 0x41, 0x6c, 0x72, 0x65, 0x61, 0x64, + 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x2e, 0x72, 0x65, 0x75, 0x73, 0x65, 0x5f, + 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x66, 0x5f, 0x61, 0x6c, 0x72, 0x65, + 0x61, 0x64, 0x79, 0x5f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x5f, 0x62, 0x79, 0x5f, 0x65, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x27, + 0x72, 0x65, 0x75, 0x73, 0x65, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x66, 0x41, + 0x6c, 0x72, 0x65, 0x61, 0x64, 0x79, 0x45, 0x78, 0x69, 0x73, 0x74, 0x42, 0x79, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x22, 0x91, 0x01, 0x0a, 0x1a, 0x50, 0x75, 0x74, 0x4c, + 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x42, 0x02, 0x10, + 0x01, 0x52, 0x0c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, + 0x25, 0x0a, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x03, 0x42, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x49, 0x64, 0x73, 0x12, 0x23, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x03, 0x42, 0x02, 0x10, 0x01, 0x52, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x73, 0x22, 0xdb, 0x03, 0x0a, 0x0f, + 0x50, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x40, 0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x61, 0x6e, 0x5f, 0x61, 0x64, 0x64, + 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x63, + 0x61, 0x6e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x63, + 0x61, 0x6e, 0x5f, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x63, 0x61, 0x6e, 0x4f, 0x6d, 0x69, 0x74, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x11, 0x63, 0x61, 0x6e, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x42, 0x02, + 0x18, 0x01, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x46, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x73, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x04, 0x74, + 0x72, 0x75, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x61, 0x6c, 0x6c, 0x46, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x10, 0x50, 0x75, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, + 0x0a, 0x11, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0f, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x03, 0x52, 0x10, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x73, 0x12, 0x28, 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x03, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x49, + 0x64, 0x73, 0x22, 0xd8, 0x02, 0x0a, 0x15, 0x50, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x61, 0x6e, + 0x5f, 0x61, 0x64, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0c, 0x63, 0x61, 0x6e, 0x41, 0x64, 0x64, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, + 0x26, 0x0a, 0x0f, 0x63, 0x61, 0x6e, 0x5f, 0x6f, 0x6d, 0x69, 0x74, 0x5f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x63, 0x61, 0x6e, 0x4f, 0x6d, 0x69, + 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x11, 0x63, 0x61, 0x6e, 0x5f, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0f, 0x63, 0x61, 0x6e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x5f, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x73, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x08, 0x3a, 0x04, 0x74, 0x72, 0x75, 0x65, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0e, 0x61, 0x6c, 0x6c, + 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x13, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x31, 0x0a, + 0x16, 0x50, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, + 0x22, 0xd5, 0x01, 0x0a, 0x12, 0x50, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, + 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x75, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x36, 0x0a, 0x13, 0x50, 0x75, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x73, + 0x22, 0xf5, 0x01, 0x0a, 0x25, 0x50, 0x75, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0c, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x18, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3c, 0x0a, 0x0c, 0x61, 0x73, 0x73, 0x6f, + 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x73, 0x73, + 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x61, 0x73, 0x73, 0x6f, 0x63, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x28, 0x0a, 0x26, 0x50, 0x75, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x6e, 0x64, 0x41, 0x73, + 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0xb1, 0x01, 0x0a, 0x18, 0x50, 0x75, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x43, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x1b, 0x0a, 0x19, 0x50, 0x75, 0x74, 0x50, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0xea, 0x01, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, + 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, + 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x79, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, + 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, + 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd8, 0x01, 0x0a, 0x1f, + 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x54, 0x79, 0x70, + 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x23, 0x0a, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x55, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, + 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x61, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x52, 0x08, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x22, 0xcd, 0x01, + 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, + 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, + 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x17, + 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x3a, 0x05, 0x66, + 0x61, 0x6c, 0x73, 0x65, 0x52, 0x15, 0x70, 0x6f, 0x70, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x91, 0x01, + 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, + 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x61, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, + 0x40, 0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x73, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x33, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x86, 0x01, + 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, + 0x55, 0x52, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x72, + 0x69, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x75, 0x72, 0x69, 0x73, 0x12, 0x50, + 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x50, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x55, 0x52, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0xa5, 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, + 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x77, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x0a, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, + 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xaa, 0x01, 0x0a, 0x16, 0x47, 0x65, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x59, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x3e, 0x0a, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x22, 0x6b, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x50, 0x0a, 0x13, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5c, + 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x61, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x61, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x6c, 0x0a, 0x18, + 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x60, 0x0a, 0x19, 0x47, 0x65, + 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x6a, 0x0a, 0x16, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x58, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x58, 0x0a, 0x21, + 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x33, 0x0a, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x22, 0x98, 0x01, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, + 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x5c, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x96, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, + 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x54, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x9b, + 0x01, 0x0a, 0x24, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x65, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x69, 0x0a, 0x25, + 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x9c, 0x01, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x6d, 0x0a, 0x26, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0x9a, 0x01, 0x0a, 0x23, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, + 0x0c, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, + 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x65, 0x0a, 0x24, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, + 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0xeb, 0x01, 0x0a, 0x1a, 0x47, 0x65, + 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, + 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, + 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, + 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xdb, 0x01, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, + 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x59, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x91, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x03, 0x52, 0x0c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x22, 0x53, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x36, 0x0a, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xab, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5d, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x41, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x22, 0x97, 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, + 0x0c, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, + 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x4d, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x94, + 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4c, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x44, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x65, 0x76, 0x65, + 0x6e, 0x74, 0x73, 0x22, 0x8a, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, 0x73, 0x12, 0x50, + 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x60, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x40, 0x0a, 0x0e, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x5f, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x52, 0x0d, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x22, 0x8b, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x69, 0x64, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, 0x49, 0x64, 0x73, 0x12, 0x50, + 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x22, 0x64, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x43, 0x0a, 0x0f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x22, 0xa9, 0x01, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, + 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x22, 0x55, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x89, 0x01, 0x0a, 0x1a, 0x47, 0x65, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, + 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x79, 0x70, 0x65, + 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x07, 0x74, 0x79, 0x70, 0x65, + 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x5c, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, + 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x22, 0xa3, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x6f, 0x0a, 0x13, 0x47, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, + 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xe9, 0x01, 0x0a, 0x18, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x75, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xd5, 0x01, + 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x42, 0x79, 0x54, 0x79, + 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x79, 0x70, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x79, 0x70, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x74, 0x79, 0x70, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x51, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, + 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x22, 0x8b, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, + 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x4b, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x73, 0x22, 0x91, 0x01, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x61, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x49, 0x64, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x51, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x94, 0x01, 0x0a, 0x1d, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x22, 0x52, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, + 0x42, 0x79, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x94, 0x01, 0x0a, 0x21, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x56, 0x0a, 0x22, + 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x23, 0x47, 0x65, 0x74, 0x43, 0x68, 0x69, 0x6c, + 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x50, 0x0a, 0x13, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x58, 0x0a, + 0x24, 0x47, 0x65, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x08, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x22, 0x9b, 0x01, 0x0a, 0x22, 0x47, 0x65, 0x74, 0x50, + 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, + 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x03, 0x42, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xe1, 0x02, 0x0a, 0x23, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, + 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x3e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, + 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x1a, 0x57, 0x0a, 0x16, 0x50, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x50, 0x65, 0x72, 0x43, 0x68, + 0x69, 0x6c, 0x64, 0x12, 0x3d, 0x0a, 0x0f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x52, 0x0e, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x73, 0x1a, 0x84, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x5d, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x47, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x50, 0x65, 0x72, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9d, 0x01, 0x0a, 0x24, 0x47, 0x65, + 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x23, 0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x42, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x63, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xf1, 0x02, 0x0a, 0x25, 0x47, 0x65, + 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x5c, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x1a, 0x5e, 0x0a, 0x19, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x50, 0x65, 0x72, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x41, + 0x0a, 0x11, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, + 0x10, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x1a, 0x89, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x62, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4c, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, + 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x50, 0x65, 0x72, 0x50, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcc, 0x01, + 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x3b, 0x0a, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x7c, 0x0a, 0x1d, + 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, + 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, + 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xcd, 0x01, 0x0a, 0x1d, 0x47, + 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4f, + 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xd2, 0x01, 0x0a, 0x1e, 0x47, + 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x36, 0x0a, + 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x50, 0x0a, + 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, + 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0xab, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x47, 0x72, + 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x07, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, + 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x13, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x50, 0x0a, + 0x17, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x08, 0x73, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x22, + 0x95, 0x02, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, + 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6d, 0x0a, + 0x1e, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, + 0x61, 0x70, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, + 0x1b, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x37, 0x0a, 0x09, + 0x72, 0x65, 0x61, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x08, 0x72, 0x65, 0x61, + 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x50, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x12, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x62, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4c, 0x69, + 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x10, 0x6c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, + 0x5f, 0x73, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4c, 0x69, + 0x6e, 0x65, 0x61, 0x67, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x0f, 0x6c, 0x69, 0x6e, 0x65, + 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x32, 0x96, 0x2c, 0x0a, 0x14, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x53, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x12, 0x5e, 0x0a, 0x0f, 0x50, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x50, 0x75, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x08, 0x50, 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x12, 0x1c, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, + 0x75, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x55, 0x0a, 0x0c, 0x50, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, + 0x20, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x50, 0x75, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x4c, 0x0a, 0x09, 0x50, 0x75, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1d, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, + 0x0a, 0x0c, 0x50, 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, + 0x75, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x67, 0x0a, 0x12, 0x50, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, + 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x12, 0x26, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x4c, 0x69, 0x6e, + 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x50, 0x75, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, + 0x0a, 0x0b, 0x50, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x1f, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x12, 0x8b, 0x01, 0x0a, 0x1e, 0x50, 0x75, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x32, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x41, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x41, 0x6e, 0x64, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x64, 0x0a, 0x11, 0x50, 0x75, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x25, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x75, 0x74, 0x50, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x23, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x12, 0x28, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, + 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x25, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x61, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x70, 0x0a, 0x15, 0x47, + 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x42, 0x79, 0x49, 0x44, 0x12, 0x29, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, + 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x12, 0x25, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x22, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x6a, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, + 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x12, 0x27, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, + 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0f, + 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, + 0x23, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x55, 0x0a, 0x0c, + 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x12, 0x20, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x58, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x21, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x52, 0x0a, + 0x0b, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x1f, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x61, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x42, 0x79, 0x49, 0x44, 0x12, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x49, 0x44, 0x12, 0x25, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x26, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x49, 0x44, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0f, 0x47, 0x65, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x49, 0x44, 0x12, 0x23, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x49, 0x44, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x67, 0x0a, 0x12, 0x47, 0x65, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, + 0x12, 0x26, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x6a, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x27, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, + 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x64, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, + 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, + 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2c, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x54, 0x79, 0x70, + 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2d, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, + 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x7c, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, + 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, + 0x0a, 0x17, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x42, 0x79, 0x54, 0x79, + 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2b, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x42, + 0x79, 0x54, 0x79, 0x70, 0x65, 0x41, 0x6e, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x64, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x55, 0x52, 0x49, 0x12, 0x25, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, + 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x55, 0x52, 0x49, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x55, + 0x52, 0x49, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x76, 0x0a, 0x17, + 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x12, 0x2b, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, + 0x79, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x44, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x44, 0x73, 0x12, 0x2a, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x49, 0x44, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, 0x6c, 0x5f, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x76, 0x65, 0x6e, + 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x49, 0x44, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7c, 0x0a, 0x19, 0x47, 0x65, 0x74, + 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x2d, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, + 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, + 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x2e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x79, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x49, 0x64, 0x73, 0x12, 0x2c, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, + 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x88, 0x01, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x31, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x8b, + 0x01, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, + 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, + 0x73, 0x12, 0x32, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, + 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, + 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x85, 0x01, 0x0a, + 0x1c, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, + 0x42, 0x79, 0x45, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x12, 0x30, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, 0x78, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x31, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x54, 0x79, 0x70, 0x65, 0x73, 0x42, 0x79, 0x45, + 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x70, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x12, 0x29, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x73, 0x42, 0x79, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x2a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x1a, 0x47, + 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, + 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x2e, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x85, 0x01, 0x0a, + 0x1c, 0x47, 0x65, 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x30, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, + 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, + 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x31, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x82, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x12, 0x2f, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x88, 0x01, 0x0a, 0x1d, 0x47, 0x65, + 0x74, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x12, 0x31, 0x2e, 0x6d, 0x6c, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x68, 0x69, + 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x42, 0x79, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x32, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x43, 0x68, 0x69, 0x6c, 0x64, 0x72, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, + 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x70, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, + 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x29, 0x2e, + 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x72, 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x66, 0x61, + 0x63, 0x74, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x12, 0x2a, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x65, 0x74, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x43, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6d, + 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5e, 0x0a, 0x0f, 0x47, + 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x12, 0x23, + 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, + 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x47, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x47, 0x72, 0x61, 0x70, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x67, 0x0a, 0x12, 0x47, + 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, + 0x68, 0x12, 0x26, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, + 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x68, 0x75, 0x62, 0x2d, 0x69, + 0x6f, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, +} + +var ( + file_ml_metadata_proto_metadata_store_service_proto_rawDescOnce sync.Once + file_ml_metadata_proto_metadata_store_service_proto_rawDescData = file_ml_metadata_proto_metadata_store_service_proto_rawDesc +) + +func file_ml_metadata_proto_metadata_store_service_proto_rawDescGZIP() []byte { + file_ml_metadata_proto_metadata_store_service_proto_rawDescOnce.Do(func() { + file_ml_metadata_proto_metadata_store_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_ml_metadata_proto_metadata_store_service_proto_rawDescData) + }) + return file_ml_metadata_proto_metadata_store_service_proto_rawDescData +} + +var file_ml_metadata_proto_metadata_store_service_proto_msgTypes = make([]protoimpl.MessageInfo, 118) +var file_ml_metadata_proto_metadata_store_service_proto_goTypes = []interface{}{ + (*ArtifactAndType)(nil), // 0: ml_metadata.ArtifactAndType + (*ArtifactStructMap)(nil), // 1: ml_metadata.ArtifactStructMap + (*ArtifactStructList)(nil), // 2: ml_metadata.ArtifactStructList + (*ArtifactStruct)(nil), // 3: ml_metadata.ArtifactStruct + (*PutArtifactsRequest)(nil), // 4: ml_metadata.PutArtifactsRequest + (*PutArtifactsResponse)(nil), // 5: ml_metadata.PutArtifactsResponse + (*PutArtifactTypeRequest)(nil), // 6: ml_metadata.PutArtifactTypeRequest + (*PutArtifactTypeResponse)(nil), // 7: ml_metadata.PutArtifactTypeResponse + (*PutExecutionsRequest)(nil), // 8: ml_metadata.PutExecutionsRequest + (*PutExecutionsResponse)(nil), // 9: ml_metadata.PutExecutionsResponse + (*PutExecutionTypeRequest)(nil), // 10: ml_metadata.PutExecutionTypeRequest + (*PutExecutionTypeResponse)(nil), // 11: ml_metadata.PutExecutionTypeResponse + (*PutEventsRequest)(nil), // 12: ml_metadata.PutEventsRequest + (*PutEventsResponse)(nil), // 13: ml_metadata.PutEventsResponse + (*PutExecutionRequest)(nil), // 14: ml_metadata.PutExecutionRequest + (*PutExecutionResponse)(nil), // 15: ml_metadata.PutExecutionResponse + (*PutLineageSubgraphRequest)(nil), // 16: ml_metadata.PutLineageSubgraphRequest + (*PutLineageSubgraphResponse)(nil), // 17: ml_metadata.PutLineageSubgraphResponse + (*PutTypesRequest)(nil), // 18: ml_metadata.PutTypesRequest + (*PutTypesResponse)(nil), // 19: ml_metadata.PutTypesResponse + (*PutContextTypeRequest)(nil), // 20: ml_metadata.PutContextTypeRequest + (*PutContextTypeResponse)(nil), // 21: ml_metadata.PutContextTypeResponse + (*PutContextsRequest)(nil), // 22: ml_metadata.PutContextsRequest + (*PutContextsResponse)(nil), // 23: ml_metadata.PutContextsResponse + (*PutAttributionsAndAssociationsRequest)(nil), // 24: ml_metadata.PutAttributionsAndAssociationsRequest + (*PutAttributionsAndAssociationsResponse)(nil), // 25: ml_metadata.PutAttributionsAndAssociationsResponse + (*PutParentContextsRequest)(nil), // 26: ml_metadata.PutParentContextsRequest + (*PutParentContextsResponse)(nil), // 27: ml_metadata.PutParentContextsResponse + (*GetArtifactsByTypeRequest)(nil), // 28: ml_metadata.GetArtifactsByTypeRequest + (*GetArtifactsByTypeResponse)(nil), // 29: ml_metadata.GetArtifactsByTypeResponse + (*GetArtifactByTypeAndNameRequest)(nil), // 30: ml_metadata.GetArtifactByTypeAndNameRequest + (*GetArtifactByTypeAndNameResponse)(nil), // 31: ml_metadata.GetArtifactByTypeAndNameResponse + (*GetArtifactsByIDRequest)(nil), // 32: ml_metadata.GetArtifactsByIDRequest + (*GetArtifactsByIDResponse)(nil), // 33: ml_metadata.GetArtifactsByIDResponse + (*GetArtifactsRequest)(nil), // 34: ml_metadata.GetArtifactsRequest + (*GetArtifactsResponse)(nil), // 35: ml_metadata.GetArtifactsResponse + (*GetArtifactsByURIRequest)(nil), // 36: ml_metadata.GetArtifactsByURIRequest + (*GetArtifactsByURIResponse)(nil), // 37: ml_metadata.GetArtifactsByURIResponse + (*GetExecutionsRequest)(nil), // 38: ml_metadata.GetExecutionsRequest + (*GetExecutionsResponse)(nil), // 39: ml_metadata.GetExecutionsResponse + (*GetArtifactTypeRequest)(nil), // 40: ml_metadata.GetArtifactTypeRequest + (*GetArtifactTypeResponse)(nil), // 41: ml_metadata.GetArtifactTypeResponse + (*GetArtifactTypesRequest)(nil), // 42: ml_metadata.GetArtifactTypesRequest + (*GetArtifactTypesResponse)(nil), // 43: ml_metadata.GetArtifactTypesResponse + (*GetExecutionTypesRequest)(nil), // 44: ml_metadata.GetExecutionTypesRequest + (*GetExecutionTypesResponse)(nil), // 45: ml_metadata.GetExecutionTypesResponse + (*GetContextTypesRequest)(nil), // 46: ml_metadata.GetContextTypesRequest + (*GetContextTypesResponse)(nil), // 47: ml_metadata.GetContextTypesResponse + (*GetArtifactsByExternalIdsRequest)(nil), // 48: ml_metadata.GetArtifactsByExternalIdsRequest + (*GetArtifactsByExternalIdsResponse)(nil), // 49: ml_metadata.GetArtifactsByExternalIdsResponse + (*GetExecutionsByExternalIdsRequest)(nil), // 50: ml_metadata.GetExecutionsByExternalIdsRequest + (*GetExecutionsByExternalIdsResponse)(nil), // 51: ml_metadata.GetExecutionsByExternalIdsResponse + (*GetContextsByExternalIdsRequest)(nil), // 52: ml_metadata.GetContextsByExternalIdsRequest + (*GetContextsByExternalIdsResponse)(nil), // 53: ml_metadata.GetContextsByExternalIdsResponse + (*GetArtifactTypesByExternalIdsRequest)(nil), // 54: ml_metadata.GetArtifactTypesByExternalIdsRequest + (*GetArtifactTypesByExternalIdsResponse)(nil), // 55: ml_metadata.GetArtifactTypesByExternalIdsResponse + (*GetExecutionTypesByExternalIdsRequest)(nil), // 56: ml_metadata.GetExecutionTypesByExternalIdsRequest + (*GetExecutionTypesByExternalIdsResponse)(nil), // 57: ml_metadata.GetExecutionTypesByExternalIdsResponse + (*GetContextTypesByExternalIdsRequest)(nil), // 58: ml_metadata.GetContextTypesByExternalIdsRequest + (*GetContextTypesByExternalIdsResponse)(nil), // 59: ml_metadata.GetContextTypesByExternalIdsResponse + (*GetExecutionsByTypeRequest)(nil), // 60: ml_metadata.GetExecutionsByTypeRequest + (*GetExecutionsByTypeResponse)(nil), // 61: ml_metadata.GetExecutionsByTypeResponse + (*GetExecutionByTypeAndNameRequest)(nil), // 62: ml_metadata.GetExecutionByTypeAndNameRequest + (*GetExecutionByTypeAndNameResponse)(nil), // 63: ml_metadata.GetExecutionByTypeAndNameResponse + (*GetExecutionsByIDRequest)(nil), // 64: ml_metadata.GetExecutionsByIDRequest + (*GetExecutionsByIDResponse)(nil), // 65: ml_metadata.GetExecutionsByIDResponse + (*GetExecutionTypeRequest)(nil), // 66: ml_metadata.GetExecutionTypeRequest + (*GetExecutionTypeResponse)(nil), // 67: ml_metadata.GetExecutionTypeResponse + (*GetEventsByExecutionIDsRequest)(nil), // 68: ml_metadata.GetEventsByExecutionIDsRequest + (*GetEventsByExecutionIDsResponse)(nil), // 69: ml_metadata.GetEventsByExecutionIDsResponse + (*GetEventsByArtifactIDsRequest)(nil), // 70: ml_metadata.GetEventsByArtifactIDsRequest + (*GetEventsByArtifactIDsResponse)(nil), // 71: ml_metadata.GetEventsByArtifactIDsResponse + (*GetArtifactTypesByIDRequest)(nil), // 72: ml_metadata.GetArtifactTypesByIDRequest + (*GetArtifactTypesByIDResponse)(nil), // 73: ml_metadata.GetArtifactTypesByIDResponse + (*GetExecutionTypesByIDRequest)(nil), // 74: ml_metadata.GetExecutionTypesByIDRequest + (*GetExecutionTypesByIDResponse)(nil), // 75: ml_metadata.GetExecutionTypesByIDResponse + (*GetContextTypeRequest)(nil), // 76: ml_metadata.GetContextTypeRequest + (*GetContextTypeResponse)(nil), // 77: ml_metadata.GetContextTypeResponse + (*GetContextTypesByIDRequest)(nil), // 78: ml_metadata.GetContextTypesByIDRequest + (*GetContextTypesByIDResponse)(nil), // 79: ml_metadata.GetContextTypesByIDResponse + (*GetContextsRequest)(nil), // 80: ml_metadata.GetContextsRequest + (*GetContextsResponse)(nil), // 81: ml_metadata.GetContextsResponse + (*GetContextsByTypeRequest)(nil), // 82: ml_metadata.GetContextsByTypeRequest + (*GetContextsByTypeResponse)(nil), // 83: ml_metadata.GetContextsByTypeResponse + (*GetContextByTypeAndNameRequest)(nil), // 84: ml_metadata.GetContextByTypeAndNameRequest + (*GetContextByTypeAndNameResponse)(nil), // 85: ml_metadata.GetContextByTypeAndNameResponse + (*GetContextsByIDRequest)(nil), // 86: ml_metadata.GetContextsByIDRequest + (*GetContextsByIDResponse)(nil), // 87: ml_metadata.GetContextsByIDResponse + (*GetContextsByArtifactRequest)(nil), // 88: ml_metadata.GetContextsByArtifactRequest + (*GetContextsByArtifactResponse)(nil), // 89: ml_metadata.GetContextsByArtifactResponse + (*GetContextsByExecutionRequest)(nil), // 90: ml_metadata.GetContextsByExecutionRequest + (*GetContextsByExecutionResponse)(nil), // 91: ml_metadata.GetContextsByExecutionResponse + (*GetParentContextsByContextRequest)(nil), // 92: ml_metadata.GetParentContextsByContextRequest + (*GetParentContextsByContextResponse)(nil), // 93: ml_metadata.GetParentContextsByContextResponse + (*GetChildrenContextsByContextRequest)(nil), // 94: ml_metadata.GetChildrenContextsByContextRequest + (*GetChildrenContextsByContextResponse)(nil), // 95: ml_metadata.GetChildrenContextsByContextResponse + (*GetParentContextsByContextsRequest)(nil), // 96: ml_metadata.GetParentContextsByContextsRequest + (*GetParentContextsByContextsResponse)(nil), // 97: ml_metadata.GetParentContextsByContextsResponse + (*GetChildrenContextsByContextsRequest)(nil), // 98: ml_metadata.GetChildrenContextsByContextsRequest + (*GetChildrenContextsByContextsResponse)(nil), // 99: ml_metadata.GetChildrenContextsByContextsResponse + (*GetArtifactsByContextRequest)(nil), // 100: ml_metadata.GetArtifactsByContextRequest + (*GetArtifactsByContextResponse)(nil), // 101: ml_metadata.GetArtifactsByContextResponse + (*GetExecutionsByContextRequest)(nil), // 102: ml_metadata.GetExecutionsByContextRequest + (*GetExecutionsByContextResponse)(nil), // 103: ml_metadata.GetExecutionsByContextResponse + (*GetLineageGraphRequest)(nil), // 104: ml_metadata.GetLineageGraphRequest + (*GetLineageGraphResponse)(nil), // 105: ml_metadata.GetLineageGraphResponse + (*GetLineageSubgraphRequest)(nil), // 106: ml_metadata.GetLineageSubgraphRequest + (*GetLineageSubgraphResponse)(nil), // 107: ml_metadata.GetLineageSubgraphResponse + nil, // 108: ml_metadata.ArtifactStructMap.PropertiesEntry + (*PutArtifactsRequest_Options)(nil), // 109: ml_metadata.PutArtifactsRequest.Options + (*PutExecutionRequest_ArtifactAndEvent)(nil), // 110: ml_metadata.PutExecutionRequest.ArtifactAndEvent + (*PutExecutionRequest_Options)(nil), // 111: ml_metadata.PutExecutionRequest.Options + (*PutLineageSubgraphRequest_EventEdge)(nil), // 112: ml_metadata.PutLineageSubgraphRequest.EventEdge + (*PutLineageSubgraphRequest_Options)(nil), // 113: ml_metadata.PutLineageSubgraphRequest.Options + (*GetParentContextsByContextsResponse_ParentContextsPerChild)(nil), // 114: ml_metadata.GetParentContextsByContextsResponse.ParentContextsPerChild + nil, // 115: ml_metadata.GetParentContextsByContextsResponse.ContextsEntry + (*GetChildrenContextsByContextsResponse_ChildrenContextsPerParent)(nil), // 116: ml_metadata.GetChildrenContextsByContextsResponse.ChildrenContextsPerParent + nil, // 117: ml_metadata.GetChildrenContextsByContextsResponse.ContextsEntry + (*Artifact)(nil), // 118: ml_metadata.Artifact + (*ArtifactType)(nil), // 119: ml_metadata.ArtifactType + (*TransactionOptions)(nil), // 120: ml_metadata.TransactionOptions + (*fieldmaskpb.FieldMask)(nil), // 121: google.protobuf.FieldMask + (*Execution)(nil), // 122: ml_metadata.Execution + (*ExecutionType)(nil), // 123: ml_metadata.ExecutionType + (*Event)(nil), // 124: ml_metadata.Event + (*Context)(nil), // 125: ml_metadata.Context + (*ContextType)(nil), // 126: ml_metadata.ContextType + (*Attribution)(nil), // 127: ml_metadata.Attribution + (*Association)(nil), // 128: ml_metadata.Association + (*ParentContext)(nil), // 129: ml_metadata.ParentContext + (*ListOperationOptions)(nil), // 130: ml_metadata.ListOperationOptions + (*LineageGraphQueryOptions)(nil), // 131: ml_metadata.LineageGraphQueryOptions + (*LineageGraph)(nil), // 132: ml_metadata.LineageGraph + (*LineageSubgraphQueryOptions)(nil), // 133: ml_metadata.LineageSubgraphQueryOptions +} +var file_ml_metadata_proto_metadata_store_service_proto_depIdxs = []int32{ + 118, // 0: ml_metadata.ArtifactAndType.artifact:type_name -> ml_metadata.Artifact + 119, // 1: ml_metadata.ArtifactAndType.type:type_name -> ml_metadata.ArtifactType + 108, // 2: ml_metadata.ArtifactStructMap.properties:type_name -> ml_metadata.ArtifactStructMap.PropertiesEntry + 3, // 3: ml_metadata.ArtifactStructList.elements:type_name -> ml_metadata.ArtifactStruct + 0, // 4: ml_metadata.ArtifactStruct.artifact:type_name -> ml_metadata.ArtifactAndType + 1, // 5: ml_metadata.ArtifactStruct.map:type_name -> ml_metadata.ArtifactStructMap + 2, // 6: ml_metadata.ArtifactStruct.list:type_name -> ml_metadata.ArtifactStructList + 118, // 7: ml_metadata.PutArtifactsRequest.artifacts:type_name -> ml_metadata.Artifact + 109, // 8: ml_metadata.PutArtifactsRequest.options:type_name -> ml_metadata.PutArtifactsRequest.Options + 120, // 9: ml_metadata.PutArtifactsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 121, // 10: ml_metadata.PutArtifactsRequest.update_mask:type_name -> google.protobuf.FieldMask + 119, // 11: ml_metadata.PutArtifactTypeRequest.artifact_type:type_name -> ml_metadata.ArtifactType + 120, // 12: ml_metadata.PutArtifactTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 13: ml_metadata.PutExecutionsRequest.executions:type_name -> ml_metadata.Execution + 120, // 14: ml_metadata.PutExecutionsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 121, // 15: ml_metadata.PutExecutionsRequest.update_mask:type_name -> google.protobuf.FieldMask + 123, // 16: ml_metadata.PutExecutionTypeRequest.execution_type:type_name -> ml_metadata.ExecutionType + 120, // 17: ml_metadata.PutExecutionTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 124, // 18: ml_metadata.PutEventsRequest.events:type_name -> ml_metadata.Event + 120, // 19: ml_metadata.PutEventsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 20: ml_metadata.PutExecutionRequest.execution:type_name -> ml_metadata.Execution + 110, // 21: ml_metadata.PutExecutionRequest.artifact_event_pairs:type_name -> ml_metadata.PutExecutionRequest.ArtifactAndEvent + 125, // 22: ml_metadata.PutExecutionRequest.contexts:type_name -> ml_metadata.Context + 111, // 23: ml_metadata.PutExecutionRequest.options:type_name -> ml_metadata.PutExecutionRequest.Options + 120, // 24: ml_metadata.PutExecutionRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 25: ml_metadata.PutLineageSubgraphRequest.executions:type_name -> ml_metadata.Execution + 118, // 26: ml_metadata.PutLineageSubgraphRequest.artifacts:type_name -> ml_metadata.Artifact + 125, // 27: ml_metadata.PutLineageSubgraphRequest.contexts:type_name -> ml_metadata.Context + 112, // 28: ml_metadata.PutLineageSubgraphRequest.event_edges:type_name -> ml_metadata.PutLineageSubgraphRequest.EventEdge + 113, // 29: ml_metadata.PutLineageSubgraphRequest.options:type_name -> ml_metadata.PutLineageSubgraphRequest.Options + 120, // 30: ml_metadata.PutLineageSubgraphRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 119, // 31: ml_metadata.PutTypesRequest.artifact_types:type_name -> ml_metadata.ArtifactType + 123, // 32: ml_metadata.PutTypesRequest.execution_types:type_name -> ml_metadata.ExecutionType + 126, // 33: ml_metadata.PutTypesRequest.context_types:type_name -> ml_metadata.ContextType + 120, // 34: ml_metadata.PutTypesRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 126, // 35: ml_metadata.PutContextTypeRequest.context_type:type_name -> ml_metadata.ContextType + 120, // 36: ml_metadata.PutContextTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 37: ml_metadata.PutContextsRequest.contexts:type_name -> ml_metadata.Context + 120, // 38: ml_metadata.PutContextsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 121, // 39: ml_metadata.PutContextsRequest.update_mask:type_name -> google.protobuf.FieldMask + 127, // 40: ml_metadata.PutAttributionsAndAssociationsRequest.attributions:type_name -> ml_metadata.Attribution + 128, // 41: ml_metadata.PutAttributionsAndAssociationsRequest.associations:type_name -> ml_metadata.Association + 120, // 42: ml_metadata.PutAttributionsAndAssociationsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 129, // 43: ml_metadata.PutParentContextsRequest.parent_contexts:type_name -> ml_metadata.ParentContext + 120, // 44: ml_metadata.PutParentContextsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 130, // 45: ml_metadata.GetArtifactsByTypeRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 46: ml_metadata.GetArtifactsByTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 118, // 47: ml_metadata.GetArtifactsByTypeResponse.artifacts:type_name -> ml_metadata.Artifact + 120, // 48: ml_metadata.GetArtifactByTypeAndNameRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 118, // 49: ml_metadata.GetArtifactByTypeAndNameResponse.artifact:type_name -> ml_metadata.Artifact + 120, // 50: ml_metadata.GetArtifactsByIDRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 118, // 51: ml_metadata.GetArtifactsByIDResponse.artifacts:type_name -> ml_metadata.Artifact + 119, // 52: ml_metadata.GetArtifactsByIDResponse.artifact_types:type_name -> ml_metadata.ArtifactType + 130, // 53: ml_metadata.GetArtifactsRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 54: ml_metadata.GetArtifactsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 118, // 55: ml_metadata.GetArtifactsResponse.artifacts:type_name -> ml_metadata.Artifact + 120, // 56: ml_metadata.GetArtifactsByURIRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 118, // 57: ml_metadata.GetArtifactsByURIResponse.artifacts:type_name -> ml_metadata.Artifact + 130, // 58: ml_metadata.GetExecutionsRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 59: ml_metadata.GetExecutionsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 60: ml_metadata.GetExecutionsResponse.executions:type_name -> ml_metadata.Execution + 120, // 61: ml_metadata.GetArtifactTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 119, // 62: ml_metadata.GetArtifactTypeResponse.artifact_type:type_name -> ml_metadata.ArtifactType + 120, // 63: ml_metadata.GetArtifactTypesRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 119, // 64: ml_metadata.GetArtifactTypesResponse.artifact_types:type_name -> ml_metadata.ArtifactType + 120, // 65: ml_metadata.GetExecutionTypesRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 123, // 66: ml_metadata.GetExecutionTypesResponse.execution_types:type_name -> ml_metadata.ExecutionType + 120, // 67: ml_metadata.GetContextTypesRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 126, // 68: ml_metadata.GetContextTypesResponse.context_types:type_name -> ml_metadata.ContextType + 120, // 69: ml_metadata.GetArtifactsByExternalIdsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 118, // 70: ml_metadata.GetArtifactsByExternalIdsResponse.artifacts:type_name -> ml_metadata.Artifact + 120, // 71: ml_metadata.GetExecutionsByExternalIdsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 72: ml_metadata.GetExecutionsByExternalIdsResponse.executions:type_name -> ml_metadata.Execution + 120, // 73: ml_metadata.GetContextsByExternalIdsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 74: ml_metadata.GetContextsByExternalIdsResponse.contexts:type_name -> ml_metadata.Context + 120, // 75: ml_metadata.GetArtifactTypesByExternalIdsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 119, // 76: ml_metadata.GetArtifactTypesByExternalIdsResponse.artifact_types:type_name -> ml_metadata.ArtifactType + 120, // 77: ml_metadata.GetExecutionTypesByExternalIdsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 123, // 78: ml_metadata.GetExecutionTypesByExternalIdsResponse.execution_types:type_name -> ml_metadata.ExecutionType + 120, // 79: ml_metadata.GetContextTypesByExternalIdsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 126, // 80: ml_metadata.GetContextTypesByExternalIdsResponse.context_types:type_name -> ml_metadata.ContextType + 130, // 81: ml_metadata.GetExecutionsByTypeRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 82: ml_metadata.GetExecutionsByTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 83: ml_metadata.GetExecutionsByTypeResponse.executions:type_name -> ml_metadata.Execution + 120, // 84: ml_metadata.GetExecutionByTypeAndNameRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 85: ml_metadata.GetExecutionByTypeAndNameResponse.execution:type_name -> ml_metadata.Execution + 120, // 86: ml_metadata.GetExecutionsByIDRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 87: ml_metadata.GetExecutionsByIDResponse.executions:type_name -> ml_metadata.Execution + 120, // 88: ml_metadata.GetExecutionTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 123, // 89: ml_metadata.GetExecutionTypeResponse.execution_type:type_name -> ml_metadata.ExecutionType + 120, // 90: ml_metadata.GetEventsByExecutionIDsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 124, // 91: ml_metadata.GetEventsByExecutionIDsResponse.events:type_name -> ml_metadata.Event + 120, // 92: ml_metadata.GetEventsByArtifactIDsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 124, // 93: ml_metadata.GetEventsByArtifactIDsResponse.events:type_name -> ml_metadata.Event + 120, // 94: ml_metadata.GetArtifactTypesByIDRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 119, // 95: ml_metadata.GetArtifactTypesByIDResponse.artifact_types:type_name -> ml_metadata.ArtifactType + 120, // 96: ml_metadata.GetExecutionTypesByIDRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 123, // 97: ml_metadata.GetExecutionTypesByIDResponse.execution_types:type_name -> ml_metadata.ExecutionType + 120, // 98: ml_metadata.GetContextTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 126, // 99: ml_metadata.GetContextTypeResponse.context_type:type_name -> ml_metadata.ContextType + 120, // 100: ml_metadata.GetContextTypesByIDRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 126, // 101: ml_metadata.GetContextTypesByIDResponse.context_types:type_name -> ml_metadata.ContextType + 130, // 102: ml_metadata.GetContextsRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 103: ml_metadata.GetContextsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 104: ml_metadata.GetContextsResponse.contexts:type_name -> ml_metadata.Context + 130, // 105: ml_metadata.GetContextsByTypeRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 106: ml_metadata.GetContextsByTypeRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 107: ml_metadata.GetContextsByTypeResponse.contexts:type_name -> ml_metadata.Context + 120, // 108: ml_metadata.GetContextByTypeAndNameRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 109: ml_metadata.GetContextByTypeAndNameResponse.context:type_name -> ml_metadata.Context + 120, // 110: ml_metadata.GetContextsByIDRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 111: ml_metadata.GetContextsByIDResponse.contexts:type_name -> ml_metadata.Context + 120, // 112: ml_metadata.GetContextsByArtifactRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 113: ml_metadata.GetContextsByArtifactResponse.contexts:type_name -> ml_metadata.Context + 120, // 114: ml_metadata.GetContextsByExecutionRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 115: ml_metadata.GetContextsByExecutionResponse.contexts:type_name -> ml_metadata.Context + 120, // 116: ml_metadata.GetParentContextsByContextRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 117: ml_metadata.GetParentContextsByContextResponse.contexts:type_name -> ml_metadata.Context + 120, // 118: ml_metadata.GetChildrenContextsByContextRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 125, // 119: ml_metadata.GetChildrenContextsByContextResponse.contexts:type_name -> ml_metadata.Context + 120, // 120: ml_metadata.GetParentContextsByContextsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 115, // 121: ml_metadata.GetParentContextsByContextsResponse.contexts:type_name -> ml_metadata.GetParentContextsByContextsResponse.ContextsEntry + 120, // 122: ml_metadata.GetChildrenContextsByContextsRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 117, // 123: ml_metadata.GetChildrenContextsByContextsResponse.contexts:type_name -> ml_metadata.GetChildrenContextsByContextsResponse.ContextsEntry + 130, // 124: ml_metadata.GetArtifactsByContextRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 125: ml_metadata.GetArtifactsByContextRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 118, // 126: ml_metadata.GetArtifactsByContextResponse.artifacts:type_name -> ml_metadata.Artifact + 130, // 127: ml_metadata.GetExecutionsByContextRequest.options:type_name -> ml_metadata.ListOperationOptions + 120, // 128: ml_metadata.GetExecutionsByContextRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 122, // 129: ml_metadata.GetExecutionsByContextResponse.executions:type_name -> ml_metadata.Execution + 120, // 130: ml_metadata.GetExecutionsByContextResponse.transaction_options:type_name -> ml_metadata.TransactionOptions + 131, // 131: ml_metadata.GetLineageGraphRequest.options:type_name -> ml_metadata.LineageGraphQueryOptions + 120, // 132: ml_metadata.GetLineageGraphRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 132, // 133: ml_metadata.GetLineageGraphResponse.subgraph:type_name -> ml_metadata.LineageGraph + 133, // 134: ml_metadata.GetLineageSubgraphRequest.lineage_subgraph_query_options:type_name -> ml_metadata.LineageSubgraphQueryOptions + 121, // 135: ml_metadata.GetLineageSubgraphRequest.read_mask:type_name -> google.protobuf.FieldMask + 120, // 136: ml_metadata.GetLineageSubgraphRequest.transaction_options:type_name -> ml_metadata.TransactionOptions + 132, // 137: ml_metadata.GetLineageSubgraphResponse.lineage_subgraph:type_name -> ml_metadata.LineageGraph + 3, // 138: ml_metadata.ArtifactStructMap.PropertiesEntry.value:type_name -> ml_metadata.ArtifactStruct + 118, // 139: ml_metadata.PutExecutionRequest.ArtifactAndEvent.artifact:type_name -> ml_metadata.Artifact + 124, // 140: ml_metadata.PutExecutionRequest.ArtifactAndEvent.event:type_name -> ml_metadata.Event + 124, // 141: ml_metadata.PutLineageSubgraphRequest.EventEdge.event:type_name -> ml_metadata.Event + 125, // 142: ml_metadata.GetParentContextsByContextsResponse.ParentContextsPerChild.parent_contexts:type_name -> ml_metadata.Context + 114, // 143: ml_metadata.GetParentContextsByContextsResponse.ContextsEntry.value:type_name -> ml_metadata.GetParentContextsByContextsResponse.ParentContextsPerChild + 125, // 144: ml_metadata.GetChildrenContextsByContextsResponse.ChildrenContextsPerParent.children_contexts:type_name -> ml_metadata.Context + 116, // 145: ml_metadata.GetChildrenContextsByContextsResponse.ContextsEntry.value:type_name -> ml_metadata.GetChildrenContextsByContextsResponse.ChildrenContextsPerParent + 6, // 146: ml_metadata.MetadataStoreService.PutArtifactType:input_type -> ml_metadata.PutArtifactTypeRequest + 10, // 147: ml_metadata.MetadataStoreService.PutExecutionType:input_type -> ml_metadata.PutExecutionTypeRequest + 20, // 148: ml_metadata.MetadataStoreService.PutContextType:input_type -> ml_metadata.PutContextTypeRequest + 18, // 149: ml_metadata.MetadataStoreService.PutTypes:input_type -> ml_metadata.PutTypesRequest + 4, // 150: ml_metadata.MetadataStoreService.PutArtifacts:input_type -> ml_metadata.PutArtifactsRequest + 8, // 151: ml_metadata.MetadataStoreService.PutExecutions:input_type -> ml_metadata.PutExecutionsRequest + 12, // 152: ml_metadata.MetadataStoreService.PutEvents:input_type -> ml_metadata.PutEventsRequest + 14, // 153: ml_metadata.MetadataStoreService.PutExecution:input_type -> ml_metadata.PutExecutionRequest + 16, // 154: ml_metadata.MetadataStoreService.PutLineageSubgraph:input_type -> ml_metadata.PutLineageSubgraphRequest + 22, // 155: ml_metadata.MetadataStoreService.PutContexts:input_type -> ml_metadata.PutContextsRequest + 24, // 156: ml_metadata.MetadataStoreService.PutAttributionsAndAssociations:input_type -> ml_metadata.PutAttributionsAndAssociationsRequest + 26, // 157: ml_metadata.MetadataStoreService.PutParentContexts:input_type -> ml_metadata.PutParentContextsRequest + 40, // 158: ml_metadata.MetadataStoreService.GetArtifactType:input_type -> ml_metadata.GetArtifactTypeRequest + 72, // 159: ml_metadata.MetadataStoreService.GetArtifactTypesByID:input_type -> ml_metadata.GetArtifactTypesByIDRequest + 42, // 160: ml_metadata.MetadataStoreService.GetArtifactTypes:input_type -> ml_metadata.GetArtifactTypesRequest + 66, // 161: ml_metadata.MetadataStoreService.GetExecutionType:input_type -> ml_metadata.GetExecutionTypeRequest + 74, // 162: ml_metadata.MetadataStoreService.GetExecutionTypesByID:input_type -> ml_metadata.GetExecutionTypesByIDRequest + 44, // 163: ml_metadata.MetadataStoreService.GetExecutionTypes:input_type -> ml_metadata.GetExecutionTypesRequest + 76, // 164: ml_metadata.MetadataStoreService.GetContextType:input_type -> ml_metadata.GetContextTypeRequest + 78, // 165: ml_metadata.MetadataStoreService.GetContextTypesByID:input_type -> ml_metadata.GetContextTypesByIDRequest + 46, // 166: ml_metadata.MetadataStoreService.GetContextTypes:input_type -> ml_metadata.GetContextTypesRequest + 34, // 167: ml_metadata.MetadataStoreService.GetArtifacts:input_type -> ml_metadata.GetArtifactsRequest + 38, // 168: ml_metadata.MetadataStoreService.GetExecutions:input_type -> ml_metadata.GetExecutionsRequest + 80, // 169: ml_metadata.MetadataStoreService.GetContexts:input_type -> ml_metadata.GetContextsRequest + 32, // 170: ml_metadata.MetadataStoreService.GetArtifactsByID:input_type -> ml_metadata.GetArtifactsByIDRequest + 64, // 171: ml_metadata.MetadataStoreService.GetExecutionsByID:input_type -> ml_metadata.GetExecutionsByIDRequest + 86, // 172: ml_metadata.MetadataStoreService.GetContextsByID:input_type -> ml_metadata.GetContextsByIDRequest + 28, // 173: ml_metadata.MetadataStoreService.GetArtifactsByType:input_type -> ml_metadata.GetArtifactsByTypeRequest + 60, // 174: ml_metadata.MetadataStoreService.GetExecutionsByType:input_type -> ml_metadata.GetExecutionsByTypeRequest + 82, // 175: ml_metadata.MetadataStoreService.GetContextsByType:input_type -> ml_metadata.GetContextsByTypeRequest + 30, // 176: ml_metadata.MetadataStoreService.GetArtifactByTypeAndName:input_type -> ml_metadata.GetArtifactByTypeAndNameRequest + 62, // 177: ml_metadata.MetadataStoreService.GetExecutionByTypeAndName:input_type -> ml_metadata.GetExecutionByTypeAndNameRequest + 84, // 178: ml_metadata.MetadataStoreService.GetContextByTypeAndName:input_type -> ml_metadata.GetContextByTypeAndNameRequest + 36, // 179: ml_metadata.MetadataStoreService.GetArtifactsByURI:input_type -> ml_metadata.GetArtifactsByURIRequest + 68, // 180: ml_metadata.MetadataStoreService.GetEventsByExecutionIDs:input_type -> ml_metadata.GetEventsByExecutionIDsRequest + 70, // 181: ml_metadata.MetadataStoreService.GetEventsByArtifactIDs:input_type -> ml_metadata.GetEventsByArtifactIDsRequest + 48, // 182: ml_metadata.MetadataStoreService.GetArtifactsByExternalIds:input_type -> ml_metadata.GetArtifactsByExternalIdsRequest + 50, // 183: ml_metadata.MetadataStoreService.GetExecutionsByExternalIds:input_type -> ml_metadata.GetExecutionsByExternalIdsRequest + 52, // 184: ml_metadata.MetadataStoreService.GetContextsByExternalIds:input_type -> ml_metadata.GetContextsByExternalIdsRequest + 54, // 185: ml_metadata.MetadataStoreService.GetArtifactTypesByExternalIds:input_type -> ml_metadata.GetArtifactTypesByExternalIdsRequest + 56, // 186: ml_metadata.MetadataStoreService.GetExecutionTypesByExternalIds:input_type -> ml_metadata.GetExecutionTypesByExternalIdsRequest + 58, // 187: ml_metadata.MetadataStoreService.GetContextTypesByExternalIds:input_type -> ml_metadata.GetContextTypesByExternalIdsRequest + 88, // 188: ml_metadata.MetadataStoreService.GetContextsByArtifact:input_type -> ml_metadata.GetContextsByArtifactRequest + 90, // 189: ml_metadata.MetadataStoreService.GetContextsByExecution:input_type -> ml_metadata.GetContextsByExecutionRequest + 92, // 190: ml_metadata.MetadataStoreService.GetParentContextsByContext:input_type -> ml_metadata.GetParentContextsByContextRequest + 94, // 191: ml_metadata.MetadataStoreService.GetChildrenContextsByContext:input_type -> ml_metadata.GetChildrenContextsByContextRequest + 96, // 192: ml_metadata.MetadataStoreService.GetParentContextsByContexts:input_type -> ml_metadata.GetParentContextsByContextsRequest + 98, // 193: ml_metadata.MetadataStoreService.GetChildrenContextsByContexts:input_type -> ml_metadata.GetChildrenContextsByContextsRequest + 100, // 194: ml_metadata.MetadataStoreService.GetArtifactsByContext:input_type -> ml_metadata.GetArtifactsByContextRequest + 102, // 195: ml_metadata.MetadataStoreService.GetExecutionsByContext:input_type -> ml_metadata.GetExecutionsByContextRequest + 104, // 196: ml_metadata.MetadataStoreService.GetLineageGraph:input_type -> ml_metadata.GetLineageGraphRequest + 106, // 197: ml_metadata.MetadataStoreService.GetLineageSubgraph:input_type -> ml_metadata.GetLineageSubgraphRequest + 7, // 198: ml_metadata.MetadataStoreService.PutArtifactType:output_type -> ml_metadata.PutArtifactTypeResponse + 11, // 199: ml_metadata.MetadataStoreService.PutExecutionType:output_type -> ml_metadata.PutExecutionTypeResponse + 21, // 200: ml_metadata.MetadataStoreService.PutContextType:output_type -> ml_metadata.PutContextTypeResponse + 19, // 201: ml_metadata.MetadataStoreService.PutTypes:output_type -> ml_metadata.PutTypesResponse + 5, // 202: ml_metadata.MetadataStoreService.PutArtifacts:output_type -> ml_metadata.PutArtifactsResponse + 9, // 203: ml_metadata.MetadataStoreService.PutExecutions:output_type -> ml_metadata.PutExecutionsResponse + 13, // 204: ml_metadata.MetadataStoreService.PutEvents:output_type -> ml_metadata.PutEventsResponse + 15, // 205: ml_metadata.MetadataStoreService.PutExecution:output_type -> ml_metadata.PutExecutionResponse + 17, // 206: ml_metadata.MetadataStoreService.PutLineageSubgraph:output_type -> ml_metadata.PutLineageSubgraphResponse + 23, // 207: ml_metadata.MetadataStoreService.PutContexts:output_type -> ml_metadata.PutContextsResponse + 25, // 208: ml_metadata.MetadataStoreService.PutAttributionsAndAssociations:output_type -> ml_metadata.PutAttributionsAndAssociationsResponse + 27, // 209: ml_metadata.MetadataStoreService.PutParentContexts:output_type -> ml_metadata.PutParentContextsResponse + 41, // 210: ml_metadata.MetadataStoreService.GetArtifactType:output_type -> ml_metadata.GetArtifactTypeResponse + 73, // 211: ml_metadata.MetadataStoreService.GetArtifactTypesByID:output_type -> ml_metadata.GetArtifactTypesByIDResponse + 43, // 212: ml_metadata.MetadataStoreService.GetArtifactTypes:output_type -> ml_metadata.GetArtifactTypesResponse + 67, // 213: ml_metadata.MetadataStoreService.GetExecutionType:output_type -> ml_metadata.GetExecutionTypeResponse + 75, // 214: ml_metadata.MetadataStoreService.GetExecutionTypesByID:output_type -> ml_metadata.GetExecutionTypesByIDResponse + 45, // 215: ml_metadata.MetadataStoreService.GetExecutionTypes:output_type -> ml_metadata.GetExecutionTypesResponse + 77, // 216: ml_metadata.MetadataStoreService.GetContextType:output_type -> ml_metadata.GetContextTypeResponse + 79, // 217: ml_metadata.MetadataStoreService.GetContextTypesByID:output_type -> ml_metadata.GetContextTypesByIDResponse + 47, // 218: ml_metadata.MetadataStoreService.GetContextTypes:output_type -> ml_metadata.GetContextTypesResponse + 35, // 219: ml_metadata.MetadataStoreService.GetArtifacts:output_type -> ml_metadata.GetArtifactsResponse + 39, // 220: ml_metadata.MetadataStoreService.GetExecutions:output_type -> ml_metadata.GetExecutionsResponse + 81, // 221: ml_metadata.MetadataStoreService.GetContexts:output_type -> ml_metadata.GetContextsResponse + 33, // 222: ml_metadata.MetadataStoreService.GetArtifactsByID:output_type -> ml_metadata.GetArtifactsByIDResponse + 65, // 223: ml_metadata.MetadataStoreService.GetExecutionsByID:output_type -> ml_metadata.GetExecutionsByIDResponse + 87, // 224: ml_metadata.MetadataStoreService.GetContextsByID:output_type -> ml_metadata.GetContextsByIDResponse + 29, // 225: ml_metadata.MetadataStoreService.GetArtifactsByType:output_type -> ml_metadata.GetArtifactsByTypeResponse + 61, // 226: ml_metadata.MetadataStoreService.GetExecutionsByType:output_type -> ml_metadata.GetExecutionsByTypeResponse + 83, // 227: ml_metadata.MetadataStoreService.GetContextsByType:output_type -> ml_metadata.GetContextsByTypeResponse + 31, // 228: ml_metadata.MetadataStoreService.GetArtifactByTypeAndName:output_type -> ml_metadata.GetArtifactByTypeAndNameResponse + 63, // 229: ml_metadata.MetadataStoreService.GetExecutionByTypeAndName:output_type -> ml_metadata.GetExecutionByTypeAndNameResponse + 85, // 230: ml_metadata.MetadataStoreService.GetContextByTypeAndName:output_type -> ml_metadata.GetContextByTypeAndNameResponse + 37, // 231: ml_metadata.MetadataStoreService.GetArtifactsByURI:output_type -> ml_metadata.GetArtifactsByURIResponse + 69, // 232: ml_metadata.MetadataStoreService.GetEventsByExecutionIDs:output_type -> ml_metadata.GetEventsByExecutionIDsResponse + 71, // 233: ml_metadata.MetadataStoreService.GetEventsByArtifactIDs:output_type -> ml_metadata.GetEventsByArtifactIDsResponse + 49, // 234: ml_metadata.MetadataStoreService.GetArtifactsByExternalIds:output_type -> ml_metadata.GetArtifactsByExternalIdsResponse + 51, // 235: ml_metadata.MetadataStoreService.GetExecutionsByExternalIds:output_type -> ml_metadata.GetExecutionsByExternalIdsResponse + 53, // 236: ml_metadata.MetadataStoreService.GetContextsByExternalIds:output_type -> ml_metadata.GetContextsByExternalIdsResponse + 55, // 237: ml_metadata.MetadataStoreService.GetArtifactTypesByExternalIds:output_type -> ml_metadata.GetArtifactTypesByExternalIdsResponse + 57, // 238: ml_metadata.MetadataStoreService.GetExecutionTypesByExternalIds:output_type -> ml_metadata.GetExecutionTypesByExternalIdsResponse + 59, // 239: ml_metadata.MetadataStoreService.GetContextTypesByExternalIds:output_type -> ml_metadata.GetContextTypesByExternalIdsResponse + 89, // 240: ml_metadata.MetadataStoreService.GetContextsByArtifact:output_type -> ml_metadata.GetContextsByArtifactResponse + 91, // 241: ml_metadata.MetadataStoreService.GetContextsByExecution:output_type -> ml_metadata.GetContextsByExecutionResponse + 93, // 242: ml_metadata.MetadataStoreService.GetParentContextsByContext:output_type -> ml_metadata.GetParentContextsByContextResponse + 95, // 243: ml_metadata.MetadataStoreService.GetChildrenContextsByContext:output_type -> ml_metadata.GetChildrenContextsByContextResponse + 97, // 244: ml_metadata.MetadataStoreService.GetParentContextsByContexts:output_type -> ml_metadata.GetParentContextsByContextsResponse + 99, // 245: ml_metadata.MetadataStoreService.GetChildrenContextsByContexts:output_type -> ml_metadata.GetChildrenContextsByContextsResponse + 101, // 246: ml_metadata.MetadataStoreService.GetArtifactsByContext:output_type -> ml_metadata.GetArtifactsByContextResponse + 103, // 247: ml_metadata.MetadataStoreService.GetExecutionsByContext:output_type -> ml_metadata.GetExecutionsByContextResponse + 105, // 248: ml_metadata.MetadataStoreService.GetLineageGraph:output_type -> ml_metadata.GetLineageGraphResponse + 107, // 249: ml_metadata.MetadataStoreService.GetLineageSubgraph:output_type -> ml_metadata.GetLineageSubgraphResponse + 198, // [198:250] is the sub-list for method output_type + 146, // [146:198] is the sub-list for method input_type + 146, // [146:146] is the sub-list for extension type_name + 146, // [146:146] is the sub-list for extension extendee + 0, // [0:146] is the sub-list for field type_name +} + +func init() { file_ml_metadata_proto_metadata_store_service_proto_init() } +func file_ml_metadata_proto_metadata_store_service_proto_init() { + if File_ml_metadata_proto_metadata_store_service_proto != nil { + return + } + file_ml_metadata_proto_metadata_store_proto_init() + if !protoimpl.UnsafeEnabled { + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ArtifactAndType); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ArtifactStructMap); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ArtifactStructList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ArtifactStruct); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutArtifactsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutArtifactsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutArtifactTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutArtifactTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutEventsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutEventsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutLineageSubgraphRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutLineageSubgraphResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutTypesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutTypesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutContextTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutContextTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutContextsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutContextsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutAttributionsAndAssociationsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutAttributionsAndAssociationsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutParentContextsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutParentContextsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactByTypeAndNameRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactByTypeAndNameResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByURIRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByURIResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[44].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByExternalIdsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByExternalIdsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByExternalIdsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByExternalIdsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByExternalIdsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByExternalIdsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypesByExternalIdsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypesByExternalIdsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypesByExternalIdsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypesByExternalIdsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypesByExternalIdsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypesByExternalIdsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionByTypeAndNameRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionByTypeAndNameResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[68].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEventsByExecutionIDsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEventsByExecutionIDsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[70].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEventsByArtifactIDsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[71].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetEventsByArtifactIDsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[72].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypesByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[73].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactTypesByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[74].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypesByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[75].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionTypesByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[76].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[77].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[78].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypesByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[79].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextTypesByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[80].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[81].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[82].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByTypeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[83].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByTypeResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[84].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextByTypeAndNameRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[85].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextByTypeAndNameResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[86].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByIDRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[87].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByIDResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[88].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByArtifactRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[89].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByArtifactResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[90].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByExecutionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[91].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetContextsByExecutionResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[92].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetParentContextsByContextRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[93].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetParentContextsByContextResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[94].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetChildrenContextsByContextRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[95].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetChildrenContextsByContextResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[96].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetParentContextsByContextsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[97].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetParentContextsByContextsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[98].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetChildrenContextsByContextsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[99].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetChildrenContextsByContextsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[100].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByContextRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[101].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetArtifactsByContextResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[102].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByContextRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[103].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetExecutionsByContextResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[104].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLineageGraphRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[105].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLineageGraphResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[106].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLineageSubgraphRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[107].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetLineageSubgraphResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[109].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutArtifactsRequest_Options); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[110].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionRequest_ArtifactAndEvent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[111].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutExecutionRequest_Options); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[112].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutLineageSubgraphRequest_EventEdge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[113].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PutLineageSubgraphRequest_Options); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[114].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetParentContextsByContextsResponse_ParentContextsPerChild); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[116].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetChildrenContextsByContextsResponse_ChildrenContextsPerParent); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_ml_metadata_proto_metadata_store_service_proto_msgTypes[3].OneofWrappers = []interface{}{ + (*ArtifactStruct_Artifact)(nil), + (*ArtifactStruct_Map)(nil), + (*ArtifactStruct_List)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_ml_metadata_proto_metadata_store_service_proto_rawDesc, + NumEnums: 0, + NumMessages: 118, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_ml_metadata_proto_metadata_store_service_proto_goTypes, + DependencyIndexes: file_ml_metadata_proto_metadata_store_service_proto_depIdxs, + MessageInfos: file_ml_metadata_proto_metadata_store_service_proto_msgTypes, + }.Build() + File_ml_metadata_proto_metadata_store_service_proto = out.File + file_ml_metadata_proto_metadata_store_service_proto_rawDesc = nil + file_ml_metadata_proto_metadata_store_service_proto_goTypes = nil + file_ml_metadata_proto_metadata_store_service_proto_depIdxs = nil +} diff --git a/pkg/ml_metadata/proto/metadata_store_service_grpc.pb.go b/pkg/ml_metadata/proto/metadata_store_service_grpc.pb.go new file mode 100644 index 00000000..cd3945f2 --- /dev/null +++ b/pkg/ml_metadata/proto/metadata_store_service_grpc.pb.go @@ -0,0 +1,2553 @@ +// Copyright 2019 Google LLC +// +//Licensed 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 +// +//https://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. +//============================================================================== + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.3.0 +// - protoc v3.20.3 +// source: ml_metadata/proto/metadata_store_service.proto + +package proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +const ( + MetadataStoreService_PutArtifactType_FullMethodName = "/ml_metadata.MetadataStoreService/PutArtifactType" + MetadataStoreService_PutExecutionType_FullMethodName = "/ml_metadata.MetadataStoreService/PutExecutionType" + MetadataStoreService_PutContextType_FullMethodName = "/ml_metadata.MetadataStoreService/PutContextType" + MetadataStoreService_PutTypes_FullMethodName = "/ml_metadata.MetadataStoreService/PutTypes" + MetadataStoreService_PutArtifacts_FullMethodName = "/ml_metadata.MetadataStoreService/PutArtifacts" + MetadataStoreService_PutExecutions_FullMethodName = "/ml_metadata.MetadataStoreService/PutExecutions" + MetadataStoreService_PutEvents_FullMethodName = "/ml_metadata.MetadataStoreService/PutEvents" + MetadataStoreService_PutExecution_FullMethodName = "/ml_metadata.MetadataStoreService/PutExecution" + MetadataStoreService_PutLineageSubgraph_FullMethodName = "/ml_metadata.MetadataStoreService/PutLineageSubgraph" + MetadataStoreService_PutContexts_FullMethodName = "/ml_metadata.MetadataStoreService/PutContexts" + MetadataStoreService_PutAttributionsAndAssociations_FullMethodName = "/ml_metadata.MetadataStoreService/PutAttributionsAndAssociations" + MetadataStoreService_PutParentContexts_FullMethodName = "/ml_metadata.MetadataStoreService/PutParentContexts" + MetadataStoreService_GetArtifactType_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactType" + MetadataStoreService_GetArtifactTypesByID_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactTypesByID" + MetadataStoreService_GetArtifactTypes_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactTypes" + MetadataStoreService_GetExecutionType_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionType" + MetadataStoreService_GetExecutionTypesByID_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionTypesByID" + MetadataStoreService_GetExecutionTypes_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionTypes" + MetadataStoreService_GetContextType_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextType" + MetadataStoreService_GetContextTypesByID_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextTypesByID" + MetadataStoreService_GetContextTypes_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextTypes" + MetadataStoreService_GetArtifacts_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifacts" + MetadataStoreService_GetExecutions_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutions" + MetadataStoreService_GetContexts_FullMethodName = "/ml_metadata.MetadataStoreService/GetContexts" + MetadataStoreService_GetArtifactsByID_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactsByID" + MetadataStoreService_GetExecutionsByID_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionsByID" + MetadataStoreService_GetContextsByID_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextsByID" + MetadataStoreService_GetArtifactsByType_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactsByType" + MetadataStoreService_GetExecutionsByType_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionsByType" + MetadataStoreService_GetContextsByType_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextsByType" + MetadataStoreService_GetArtifactByTypeAndName_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactByTypeAndName" + MetadataStoreService_GetExecutionByTypeAndName_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionByTypeAndName" + MetadataStoreService_GetContextByTypeAndName_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextByTypeAndName" + MetadataStoreService_GetArtifactsByURI_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactsByURI" + MetadataStoreService_GetEventsByExecutionIDs_FullMethodName = "/ml_metadata.MetadataStoreService/GetEventsByExecutionIDs" + MetadataStoreService_GetEventsByArtifactIDs_FullMethodName = "/ml_metadata.MetadataStoreService/GetEventsByArtifactIDs" + MetadataStoreService_GetArtifactsByExternalIds_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactsByExternalIds" + MetadataStoreService_GetExecutionsByExternalIds_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionsByExternalIds" + MetadataStoreService_GetContextsByExternalIds_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextsByExternalIds" + MetadataStoreService_GetArtifactTypesByExternalIds_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactTypesByExternalIds" + MetadataStoreService_GetExecutionTypesByExternalIds_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionTypesByExternalIds" + MetadataStoreService_GetContextTypesByExternalIds_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextTypesByExternalIds" + MetadataStoreService_GetContextsByArtifact_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextsByArtifact" + MetadataStoreService_GetContextsByExecution_FullMethodName = "/ml_metadata.MetadataStoreService/GetContextsByExecution" + MetadataStoreService_GetParentContextsByContext_FullMethodName = "/ml_metadata.MetadataStoreService/GetParentContextsByContext" + MetadataStoreService_GetChildrenContextsByContext_FullMethodName = "/ml_metadata.MetadataStoreService/GetChildrenContextsByContext" + MetadataStoreService_GetParentContextsByContexts_FullMethodName = "/ml_metadata.MetadataStoreService/GetParentContextsByContexts" + MetadataStoreService_GetChildrenContextsByContexts_FullMethodName = "/ml_metadata.MetadataStoreService/GetChildrenContextsByContexts" + MetadataStoreService_GetArtifactsByContext_FullMethodName = "/ml_metadata.MetadataStoreService/GetArtifactsByContext" + MetadataStoreService_GetExecutionsByContext_FullMethodName = "/ml_metadata.MetadataStoreService/GetExecutionsByContext" + MetadataStoreService_GetLineageGraph_FullMethodName = "/ml_metadata.MetadataStoreService/GetLineageGraph" + MetadataStoreService_GetLineageSubgraph_FullMethodName = "/ml_metadata.MetadataStoreService/GetLineageSubgraph" +) + +// MetadataStoreServiceClient is the client API for MetadataStoreService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type MetadataStoreServiceClient interface { + // Inserts or updates an ArtifactType. + // + // A type has a set of strong typed properties describing the schema of any + // stored instance associated with that type. A type is identified by a name + // and an optional version. + // + // Type Creation: + // If no type exists in the database with the given identifier + // (name, version), it creates a new type and returns the type_id. + // + // Type Evolution: + // If the request type with the same (name, version) already exists + // (let's call it stored_type), the method enforces the stored_type can be + // updated only when the request type is backward compatible for the already + // stored instances. + // + // Backwards compatibility is violated iff: + // + // a) there is a property where the request type and stored_type have + // different value type (e.g., int vs. string) + // b) `can_add_fields = false` and the request type has a new property that + // is not stored. + // c) `can_omit_fields = false` and stored_type has an existing property + // that is not provided in the request type. + // + // If non-backward type change is required in the application, e.g., + // deprecate properties, re-purpose property name, change value types, + // a new type can be created with a different (name, version) identifier. + // Note the type version is optional, and a version value with empty string + // is treated as unset. + // + // Args: + // + // artifact_type: the type to be inserted or updated. + // can_add_fields: + // when set to true, new properties can be added; + // when set to false, returns ALREADY_EXISTS if the request type has + // properties that are not in stored_type. + // can_omit_fields: + // when set to true, stored properties can be omitted in the request type; + // when set to false, returns ALREADY_EXISTS if the stored_type has + // properties not in the request type. + // + // Returns: + // + // The type_id of the stored type. + // + // Raises: + // + // ALREADY_EXISTS error in the case listed above. + // INVALID_ARGUMENT error, if the given type has no name, or any + // property value type is unknown. + PutArtifactType(ctx context.Context, in *PutArtifactTypeRequest, opts ...grpc.CallOption) (*PutArtifactTypeResponse, error) + // Inserts or updates an ExecutionType. Please refer to PutArtifactType for + // type upsert API description. + PutExecutionType(ctx context.Context, in *PutExecutionTypeRequest, opts ...grpc.CallOption) (*PutExecutionTypeResponse, error) + // Inserts or updates an ContextType. Please refer to PutArtifactType for + // type upsert API description. + PutContextType(ctx context.Context, in *PutContextTypeRequest, opts ...grpc.CallOption) (*PutContextTypeResponse, error) + // Bulk inserts types atomically. + PutTypes(ctx context.Context, in *PutTypesRequest, opts ...grpc.CallOption) (*PutTypesResponse, error) + // Inserts or updates artifacts in the database. + // + // If an artifact_id is specified for an artifact, it is an update. + // If an artifact_id is unspecified, it will insert a new artifact. + // For new artifacts, type must be specified. + // For old artifacts, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated artifacts will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // + // artifacts: A list of artifacts to insert or update. + // + // Returns: + // + // A list of artifact ids index-aligned with the input. + PutArtifacts(ctx context.Context, in *PutArtifactsRequest, opts ...grpc.CallOption) (*PutArtifactsResponse, error) + // Inserts or updates executions in the database. + // + // If an execution_id is specified for an execution, it is an update. + // If an execution_id is unspecified, it will insert a new execution. + // For new executions, type must be specified. + // For old executions, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated executions will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // + // executions: A list of executions to insert or update. + // + // Returns: + // + // A list of execution ids index-aligned with the input. + PutExecutions(ctx context.Context, in *PutExecutionsRequest, opts ...grpc.CallOption) (*PutExecutionsResponse, error) + // Inserts events in the database. + // + // The execution_id and artifact_id must already exist. + // Once created, events cannot be modified. + // AlreadyExists error will be raised if duplicated events are found. + // + // It is not guaranteed that the created or updated events will share the + // same `milliseconds_since_epoch` timestamps. + // + // Args: + // + // events: A list of events to insert or update. + PutEvents(ctx context.Context, in *PutEventsRequest, opts ...grpc.CallOption) (*PutEventsResponse, error) + // Inserts or updates an Execution and its input and output artifacts and + // related contexts atomically. The `artifact_event_pairs` include the state + // changes of the Artifacts used or generated by the Execution, as well as the + // input/output Event. The `contexts` describe the associations of the + // execution and the attributions of the artifacts. + // + // If an execution_id is specified, it is an update on the corresponding + // execution, otherwise it does an insertion. + // For insertion, type must be specified. Same rule applies to artifacts + // and contexts in the request. Corresponding errors may raised. For example: + // AlreadyExists error will be raised if duplicated executions, artifacts + // or events are found. + // + // It is not guaranteed that the created or updated executions, artifacts, + // contexts and events will share the same `create_time_since_epoch`, + // `last_update_time_since_epoch`, or `milliseconds_since_epoch` timestamps. + // + // Args: + // + // execution: An execution to insert or update. + // artifact_event_pairs: Artifacts to insert or update and events to insert. + // contexts: The contexts that the execution and the artifacts belong to. + // + // Returns: + // + // An execution id and a list of artifacts and contexts ids index-aligned + // with the input. + PutExecution(ctx context.Context, in *PutExecutionRequest, opts ...grpc.CallOption) (*PutExecutionResponse, error) + // Inserts or updates a lineage subgraph (i.e. a collection of event edges + // and its executions, artifacts, and related contexts) atomically. The + // `event_edges` include an Event and the indices of the corresponding + // execution and artifact from the input list of executions and artifacts. The + // `contexts` describe the associations of the Execution and the attributions + // of the Artifact. + // + // If an execution_id is specified, it is an update on the corresponding + // Execution, otherwise it does an insertion. For insertion, type must be + // specified. These rules apply to Artifacts and Contexts as well. + // Corresponding errors may be raised. For example: AlreadyExists error will + // be raised if duplicated executions, artifacts, or events are found. + // + // It is not guaranteed that the created or updated executions, artifacts, + // contexts and events will share the same `create_time_since_epoch`, + // `last_update_time_since_epoch`, or `milliseconds_since_epoch` timestamps. + // + // Args: + // + // executions: A list of executions to insert or update. + // artifacts: A list of artifacts to insert or update. + // contexts: A list of contexts to insert and/or create associations and + // attributions with. + // event_edges: A list of events to insert with the indices of the + // corresponding execution and artifact from the input lists of + // executions and artifacts. + // + // Returns: + // + // Lists of execution, artifact, and context ids index-aligned with the + // inputs. + PutLineageSubgraph(ctx context.Context, in *PutLineageSubgraphRequest, opts ...grpc.CallOption) (*PutLineageSubgraphResponse, error) + // Inserts or updates contexts in database and returns a list of context ids. + // + // If an context_id is specified for a context, it is an update. + // If an context_id is unspecified, it will insert a new context. + // For new contexts, type must be specified. + // For old contexts, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated contexts will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // + // contexts: A list of contexts to insert or update. + // + // Returns: + // + // A list of context ids index-aligned with the input. + PutContexts(ctx context.Context, in *PutContextsRequest, opts ...grpc.CallOption) (*PutContextsResponse, error) + // Inserts attribution and association relationships in the database. + // The context_id, artifact_id, and execution_id must already exist. + // If the relationship exists, this call does nothing. Once added, the + // relationships cannot be modified. + // + // Args: + // + // attributions: A list of attributions to insert. + // associations: A list of associations to insert. + PutAttributionsAndAssociations(ctx context.Context, in *PutAttributionsAndAssociationsRequest, opts ...grpc.CallOption) (*PutAttributionsAndAssociationsResponse, error) + // Inserts parental context relationships in the database. + // The ParentContext relationship has direction. The call fails if cycles are + // detected. + // + // Args: + // + // parent_contexts: A list of parent contexts to insert. + PutParentContexts(ctx context.Context, in *PutParentContextsRequest, opts ...grpc.CallOption) (*PutParentContextsResponse, error) + // Gets an artifact type. Returns a NOT_FOUND error if the type does not + // exist. + GetArtifactType(ctx context.Context, in *GetArtifactTypeRequest, opts ...grpc.CallOption) (*GetArtifactTypeResponse, error) + // Gets a list of artifact types by ID. + // If no artifact types with an ID exists, the artifact type is skipped. + GetArtifactTypesByID(ctx context.Context, in *GetArtifactTypesByIDRequest, opts ...grpc.CallOption) (*GetArtifactTypesByIDResponse, error) + // Gets a list of all artifact types. + GetArtifactTypes(ctx context.Context, in *GetArtifactTypesRequest, opts ...grpc.CallOption) (*GetArtifactTypesResponse, error) + // Gets an execution type, or None if it does not exist. + GetExecutionType(ctx context.Context, in *GetExecutionTypeRequest, opts ...grpc.CallOption) (*GetExecutionTypeResponse, error) + // Gets a list of execution types by ID. + // If no execution types with an ID exists, the execution type is skipped. + GetExecutionTypesByID(ctx context.Context, in *GetExecutionTypesByIDRequest, opts ...grpc.CallOption) (*GetExecutionTypesByIDResponse, error) + // Gets a list of all execution types. + GetExecutionTypes(ctx context.Context, in *GetExecutionTypesRequest, opts ...grpc.CallOption) (*GetExecutionTypesResponse, error) + // Gets a context type. Returns a NOT_FOUND error if the type does not exist. + GetContextType(ctx context.Context, in *GetContextTypeRequest, opts ...grpc.CallOption) (*GetContextTypeResponse, error) + // Gets a list of context types by ID. + // If no context types with an ID exists, the context type is skipped. + GetContextTypesByID(ctx context.Context, in *GetContextTypesByIDRequest, opts ...grpc.CallOption) (*GetContextTypesByIDResponse, error) + // Gets a list of all context types. + GetContextTypes(ctx context.Context, in *GetContextTypesRequest, opts ...grpc.CallOption) (*GetContextTypesResponse, error) + // Gets all the artifacts. + GetArtifacts(ctx context.Context, in *GetArtifactsRequest, opts ...grpc.CallOption) (*GetArtifactsResponse, error) + // Gets all the executions. + GetExecutions(ctx context.Context, in *GetExecutionsRequest, opts ...grpc.CallOption) (*GetExecutionsResponse, error) + // Gets all the contexts. + GetContexts(ctx context.Context, in *GetContextsRequest, opts ...grpc.CallOption) (*GetContextsResponse, error) + // Gets all artifacts with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // + // artifact_ids: A list of artifact ids to retrieve. + // + // Returns: + // + // Artifacts with matching ids. + GetArtifactsByID(ctx context.Context, in *GetArtifactsByIDRequest, opts ...grpc.CallOption) (*GetArtifactsByIDResponse, error) + // Gets all executions with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // + // execution_ids: A list of execution ids to retrieve. + GetExecutionsByID(ctx context.Context, in *GetExecutionsByIDRequest, opts ...grpc.CallOption) (*GetExecutionsByIDResponse, error) + // Gets all contexts with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // + // context_ids: A list of context ids to retrieve. + GetContextsByID(ctx context.Context, in *GetContextsByIDRequest, opts ...grpc.CallOption) (*GetContextsByIDResponse, error) + // Gets all the artifacts of a given type. + GetArtifactsByType(ctx context.Context, in *GetArtifactsByTypeRequest, opts ...grpc.CallOption) (*GetArtifactsByTypeResponse, error) + // Gets all the executions of a given type. + GetExecutionsByType(ctx context.Context, in *GetExecutionsByTypeRequest, opts ...grpc.CallOption) (*GetExecutionsByTypeResponse, error) + // Gets all the contexts of a given type. + GetContextsByType(ctx context.Context, in *GetContextsByTypeRequest, opts ...grpc.CallOption) (*GetContextsByTypeResponse, error) + // Gets the artifact of the given type and artifact name. + GetArtifactByTypeAndName(ctx context.Context, in *GetArtifactByTypeAndNameRequest, opts ...grpc.CallOption) (*GetArtifactByTypeAndNameResponse, error) + // Gets the execution of the given type and execution name. + GetExecutionByTypeAndName(ctx context.Context, in *GetExecutionByTypeAndNameRequest, opts ...grpc.CallOption) (*GetExecutionByTypeAndNameResponse, error) + // Gets the context of the given type and context name. + GetContextByTypeAndName(ctx context.Context, in *GetContextByTypeAndNameRequest, opts ...grpc.CallOption) (*GetContextByTypeAndNameResponse, error) + // Gets all the artifacts with matching uris. + GetArtifactsByURI(ctx context.Context, in *GetArtifactsByURIRequest, opts ...grpc.CallOption) (*GetArtifactsByURIResponse, error) + // Gets all events with matching execution ids. + GetEventsByExecutionIDs(ctx context.Context, in *GetEventsByExecutionIDsRequest, opts ...grpc.CallOption) (*GetEventsByExecutionIDsResponse, error) + // Gets all events with matching artifact ids. + GetEventsByArtifactIDs(ctx context.Context, in *GetEventsByArtifactIDsRequest, opts ...grpc.CallOption) (*GetEventsByArtifactIDsResponse, error) + // Gets all the artifacts with matching external ids. + GetArtifactsByExternalIds(ctx context.Context, in *GetArtifactsByExternalIdsRequest, opts ...grpc.CallOption) (*GetArtifactsByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetExecutionsByExternalIds(ctx context.Context, in *GetExecutionsByExternalIdsRequest, opts ...grpc.CallOption) (*GetExecutionsByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetContextsByExternalIds(ctx context.Context, in *GetContextsByExternalIdsRequest, opts ...grpc.CallOption) (*GetContextsByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetArtifactTypesByExternalIds(ctx context.Context, in *GetArtifactTypesByExternalIdsRequest, opts ...grpc.CallOption) (*GetArtifactTypesByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetExecutionTypesByExternalIds(ctx context.Context, in *GetExecutionTypesByExternalIdsRequest, opts ...grpc.CallOption) (*GetExecutionTypesByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetContextTypesByExternalIds(ctx context.Context, in *GetContextTypesByExternalIdsRequest, opts ...grpc.CallOption) (*GetContextTypesByExternalIdsResponse, error) + // Gets all context that an artifact is attributed to. + GetContextsByArtifact(ctx context.Context, in *GetContextsByArtifactRequest, opts ...grpc.CallOption) (*GetContextsByArtifactResponse, error) + // Gets all context that an execution is associated with. + GetContextsByExecution(ctx context.Context, in *GetContextsByExecutionRequest, opts ...grpc.CallOption) (*GetContextsByExecutionResponse, error) + // Gets all parent contexts that a context is related. + GetParentContextsByContext(ctx context.Context, in *GetParentContextsByContextRequest, opts ...grpc.CallOption) (*GetParentContextsByContextResponse, error) + // Gets all children contexts that a context is related. + GetChildrenContextsByContext(ctx context.Context, in *GetChildrenContextsByContextRequest, opts ...grpc.CallOption) (*GetChildrenContextsByContextResponse, error) + // Batch getting all the parent contexts that a list of contexts are related. + GetParentContextsByContexts(ctx context.Context, in *GetParentContextsByContextsRequest, opts ...grpc.CallOption) (*GetParentContextsByContextsResponse, error) + // Batch getting all the children contexts that a list of contexts are + // related. + GetChildrenContextsByContexts(ctx context.Context, in *GetChildrenContextsByContextsRequest, opts ...grpc.CallOption) (*GetChildrenContextsByContextsResponse, error) + // Gets all direct artifacts that a context attributes to. + GetArtifactsByContext(ctx context.Context, in *GetArtifactsByContextRequest, opts ...grpc.CallOption) (*GetArtifactsByContextResponse, error) + // Gets all direct executions that a context associates with. + GetExecutionsByContext(ctx context.Context, in *GetExecutionsByContextRequest, opts ...grpc.CallOption) (*GetExecutionsByContextResponse, error) + // TODO(b/283852485): Deprecate GetLineageGraph API after migration to + // GetLineageSubgraph API. + // The transaction performs a constrained transitive closure and returns a + // lineage subgraph satisfying the conditions and constraints specified in + // the GetLineageGraphRequest. + GetLineageGraph(ctx context.Context, in *GetLineageGraphRequest, opts ...grpc.CallOption) (*GetLineageGraphResponse, error) + // Gets a lineage subgraph by performing graph traversal from a list of + // interested nodes. + // A lineage subgraph without node details (e.g., external_id, properties) + // will be returned. + GetLineageSubgraph(ctx context.Context, in *GetLineageSubgraphRequest, opts ...grpc.CallOption) (*GetLineageSubgraphResponse, error) +} + +type metadataStoreServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewMetadataStoreServiceClient(cc grpc.ClientConnInterface) MetadataStoreServiceClient { + return &metadataStoreServiceClient{cc} +} + +func (c *metadataStoreServiceClient) PutArtifactType(ctx context.Context, in *PutArtifactTypeRequest, opts ...grpc.CallOption) (*PutArtifactTypeResponse, error) { + out := new(PutArtifactTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutArtifactType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutExecutionType(ctx context.Context, in *PutExecutionTypeRequest, opts ...grpc.CallOption) (*PutExecutionTypeResponse, error) { + out := new(PutExecutionTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutExecutionType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutContextType(ctx context.Context, in *PutContextTypeRequest, opts ...grpc.CallOption) (*PutContextTypeResponse, error) { + out := new(PutContextTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutContextType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutTypes(ctx context.Context, in *PutTypesRequest, opts ...grpc.CallOption) (*PutTypesResponse, error) { + out := new(PutTypesResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutTypes_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutArtifacts(ctx context.Context, in *PutArtifactsRequest, opts ...grpc.CallOption) (*PutArtifactsResponse, error) { + out := new(PutArtifactsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutArtifacts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutExecutions(ctx context.Context, in *PutExecutionsRequest, opts ...grpc.CallOption) (*PutExecutionsResponse, error) { + out := new(PutExecutionsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutExecutions_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutEvents(ctx context.Context, in *PutEventsRequest, opts ...grpc.CallOption) (*PutEventsResponse, error) { + out := new(PutEventsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutEvents_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutExecution(ctx context.Context, in *PutExecutionRequest, opts ...grpc.CallOption) (*PutExecutionResponse, error) { + out := new(PutExecutionResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutExecution_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutLineageSubgraph(ctx context.Context, in *PutLineageSubgraphRequest, opts ...grpc.CallOption) (*PutLineageSubgraphResponse, error) { + out := new(PutLineageSubgraphResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutLineageSubgraph_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutContexts(ctx context.Context, in *PutContextsRequest, opts ...grpc.CallOption) (*PutContextsResponse, error) { + out := new(PutContextsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutContexts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutAttributionsAndAssociations(ctx context.Context, in *PutAttributionsAndAssociationsRequest, opts ...grpc.CallOption) (*PutAttributionsAndAssociationsResponse, error) { + out := new(PutAttributionsAndAssociationsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutAttributionsAndAssociations_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) PutParentContexts(ctx context.Context, in *PutParentContextsRequest, opts ...grpc.CallOption) (*PutParentContextsResponse, error) { + out := new(PutParentContextsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_PutParentContexts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactType(ctx context.Context, in *GetArtifactTypeRequest, opts ...grpc.CallOption) (*GetArtifactTypeResponse, error) { + out := new(GetArtifactTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactTypesByID(ctx context.Context, in *GetArtifactTypesByIDRequest, opts ...grpc.CallOption) (*GetArtifactTypesByIDResponse, error) { + out := new(GetArtifactTypesByIDResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactTypesByID_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactTypes(ctx context.Context, in *GetArtifactTypesRequest, opts ...grpc.CallOption) (*GetArtifactTypesResponse, error) { + out := new(GetArtifactTypesResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactTypes_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionType(ctx context.Context, in *GetExecutionTypeRequest, opts ...grpc.CallOption) (*GetExecutionTypeResponse, error) { + out := new(GetExecutionTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionTypesByID(ctx context.Context, in *GetExecutionTypesByIDRequest, opts ...grpc.CallOption) (*GetExecutionTypesByIDResponse, error) { + out := new(GetExecutionTypesByIDResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionTypesByID_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionTypes(ctx context.Context, in *GetExecutionTypesRequest, opts ...grpc.CallOption) (*GetExecutionTypesResponse, error) { + out := new(GetExecutionTypesResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionTypes_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextType(ctx context.Context, in *GetContextTypeRequest, opts ...grpc.CallOption) (*GetContextTypeResponse, error) { + out := new(GetContextTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextTypesByID(ctx context.Context, in *GetContextTypesByIDRequest, opts ...grpc.CallOption) (*GetContextTypesByIDResponse, error) { + out := new(GetContextTypesByIDResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextTypesByID_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextTypes(ctx context.Context, in *GetContextTypesRequest, opts ...grpc.CallOption) (*GetContextTypesResponse, error) { + out := new(GetContextTypesResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextTypes_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifacts(ctx context.Context, in *GetArtifactsRequest, opts ...grpc.CallOption) (*GetArtifactsResponse, error) { + out := new(GetArtifactsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifacts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutions(ctx context.Context, in *GetExecutionsRequest, opts ...grpc.CallOption) (*GetExecutionsResponse, error) { + out := new(GetExecutionsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutions_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContexts(ctx context.Context, in *GetContextsRequest, opts ...grpc.CallOption) (*GetContextsResponse, error) { + out := new(GetContextsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContexts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactsByID(ctx context.Context, in *GetArtifactsByIDRequest, opts ...grpc.CallOption) (*GetArtifactsByIDResponse, error) { + out := new(GetArtifactsByIDResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactsByID_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionsByID(ctx context.Context, in *GetExecutionsByIDRequest, opts ...grpc.CallOption) (*GetExecutionsByIDResponse, error) { + out := new(GetExecutionsByIDResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionsByID_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextsByID(ctx context.Context, in *GetContextsByIDRequest, opts ...grpc.CallOption) (*GetContextsByIDResponse, error) { + out := new(GetContextsByIDResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextsByID_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactsByType(ctx context.Context, in *GetArtifactsByTypeRequest, opts ...grpc.CallOption) (*GetArtifactsByTypeResponse, error) { + out := new(GetArtifactsByTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactsByType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionsByType(ctx context.Context, in *GetExecutionsByTypeRequest, opts ...grpc.CallOption) (*GetExecutionsByTypeResponse, error) { + out := new(GetExecutionsByTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionsByType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextsByType(ctx context.Context, in *GetContextsByTypeRequest, opts ...grpc.CallOption) (*GetContextsByTypeResponse, error) { + out := new(GetContextsByTypeResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextsByType_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactByTypeAndName(ctx context.Context, in *GetArtifactByTypeAndNameRequest, opts ...grpc.CallOption) (*GetArtifactByTypeAndNameResponse, error) { + out := new(GetArtifactByTypeAndNameResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactByTypeAndName_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionByTypeAndName(ctx context.Context, in *GetExecutionByTypeAndNameRequest, opts ...grpc.CallOption) (*GetExecutionByTypeAndNameResponse, error) { + out := new(GetExecutionByTypeAndNameResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionByTypeAndName_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextByTypeAndName(ctx context.Context, in *GetContextByTypeAndNameRequest, opts ...grpc.CallOption) (*GetContextByTypeAndNameResponse, error) { + out := new(GetContextByTypeAndNameResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextByTypeAndName_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactsByURI(ctx context.Context, in *GetArtifactsByURIRequest, opts ...grpc.CallOption) (*GetArtifactsByURIResponse, error) { + out := new(GetArtifactsByURIResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactsByURI_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetEventsByExecutionIDs(ctx context.Context, in *GetEventsByExecutionIDsRequest, opts ...grpc.CallOption) (*GetEventsByExecutionIDsResponse, error) { + out := new(GetEventsByExecutionIDsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetEventsByExecutionIDs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetEventsByArtifactIDs(ctx context.Context, in *GetEventsByArtifactIDsRequest, opts ...grpc.CallOption) (*GetEventsByArtifactIDsResponse, error) { + out := new(GetEventsByArtifactIDsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetEventsByArtifactIDs_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactsByExternalIds(ctx context.Context, in *GetArtifactsByExternalIdsRequest, opts ...grpc.CallOption) (*GetArtifactsByExternalIdsResponse, error) { + out := new(GetArtifactsByExternalIdsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactsByExternalIds_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionsByExternalIds(ctx context.Context, in *GetExecutionsByExternalIdsRequest, opts ...grpc.CallOption) (*GetExecutionsByExternalIdsResponse, error) { + out := new(GetExecutionsByExternalIdsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionsByExternalIds_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextsByExternalIds(ctx context.Context, in *GetContextsByExternalIdsRequest, opts ...grpc.CallOption) (*GetContextsByExternalIdsResponse, error) { + out := new(GetContextsByExternalIdsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextsByExternalIds_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactTypesByExternalIds(ctx context.Context, in *GetArtifactTypesByExternalIdsRequest, opts ...grpc.CallOption) (*GetArtifactTypesByExternalIdsResponse, error) { + out := new(GetArtifactTypesByExternalIdsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactTypesByExternalIds_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionTypesByExternalIds(ctx context.Context, in *GetExecutionTypesByExternalIdsRequest, opts ...grpc.CallOption) (*GetExecutionTypesByExternalIdsResponse, error) { + out := new(GetExecutionTypesByExternalIdsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionTypesByExternalIds_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextTypesByExternalIds(ctx context.Context, in *GetContextTypesByExternalIdsRequest, opts ...grpc.CallOption) (*GetContextTypesByExternalIdsResponse, error) { + out := new(GetContextTypesByExternalIdsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextTypesByExternalIds_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextsByArtifact(ctx context.Context, in *GetContextsByArtifactRequest, opts ...grpc.CallOption) (*GetContextsByArtifactResponse, error) { + out := new(GetContextsByArtifactResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextsByArtifact_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetContextsByExecution(ctx context.Context, in *GetContextsByExecutionRequest, opts ...grpc.CallOption) (*GetContextsByExecutionResponse, error) { + out := new(GetContextsByExecutionResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetContextsByExecution_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetParentContextsByContext(ctx context.Context, in *GetParentContextsByContextRequest, opts ...grpc.CallOption) (*GetParentContextsByContextResponse, error) { + out := new(GetParentContextsByContextResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetParentContextsByContext_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetChildrenContextsByContext(ctx context.Context, in *GetChildrenContextsByContextRequest, opts ...grpc.CallOption) (*GetChildrenContextsByContextResponse, error) { + out := new(GetChildrenContextsByContextResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetChildrenContextsByContext_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetParentContextsByContexts(ctx context.Context, in *GetParentContextsByContextsRequest, opts ...grpc.CallOption) (*GetParentContextsByContextsResponse, error) { + out := new(GetParentContextsByContextsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetParentContextsByContexts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetChildrenContextsByContexts(ctx context.Context, in *GetChildrenContextsByContextsRequest, opts ...grpc.CallOption) (*GetChildrenContextsByContextsResponse, error) { + out := new(GetChildrenContextsByContextsResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetChildrenContextsByContexts_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetArtifactsByContext(ctx context.Context, in *GetArtifactsByContextRequest, opts ...grpc.CallOption) (*GetArtifactsByContextResponse, error) { + out := new(GetArtifactsByContextResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetArtifactsByContext_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetExecutionsByContext(ctx context.Context, in *GetExecutionsByContextRequest, opts ...grpc.CallOption) (*GetExecutionsByContextResponse, error) { + out := new(GetExecutionsByContextResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetExecutionsByContext_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetLineageGraph(ctx context.Context, in *GetLineageGraphRequest, opts ...grpc.CallOption) (*GetLineageGraphResponse, error) { + out := new(GetLineageGraphResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetLineageGraph_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *metadataStoreServiceClient) GetLineageSubgraph(ctx context.Context, in *GetLineageSubgraphRequest, opts ...grpc.CallOption) (*GetLineageSubgraphResponse, error) { + out := new(GetLineageSubgraphResponse) + err := c.cc.Invoke(ctx, MetadataStoreService_GetLineageSubgraph_FullMethodName, in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MetadataStoreServiceServer is the server API for MetadataStoreService service. +// All implementations must embed UnimplementedMetadataStoreServiceServer +// for forward compatibility +type MetadataStoreServiceServer interface { + // Inserts or updates an ArtifactType. + // + // A type has a set of strong typed properties describing the schema of any + // stored instance associated with that type. A type is identified by a name + // and an optional version. + // + // Type Creation: + // If no type exists in the database with the given identifier + // (name, version), it creates a new type and returns the type_id. + // + // Type Evolution: + // If the request type with the same (name, version) already exists + // (let's call it stored_type), the method enforces the stored_type can be + // updated only when the request type is backward compatible for the already + // stored instances. + // + // Backwards compatibility is violated iff: + // + // a) there is a property where the request type and stored_type have + // different value type (e.g., int vs. string) + // b) `can_add_fields = false` and the request type has a new property that + // is not stored. + // c) `can_omit_fields = false` and stored_type has an existing property + // that is not provided in the request type. + // + // If non-backward type change is required in the application, e.g., + // deprecate properties, re-purpose property name, change value types, + // a new type can be created with a different (name, version) identifier. + // Note the type version is optional, and a version value with empty string + // is treated as unset. + // + // Args: + // + // artifact_type: the type to be inserted or updated. + // can_add_fields: + // when set to true, new properties can be added; + // when set to false, returns ALREADY_EXISTS if the request type has + // properties that are not in stored_type. + // can_omit_fields: + // when set to true, stored properties can be omitted in the request type; + // when set to false, returns ALREADY_EXISTS if the stored_type has + // properties not in the request type. + // + // Returns: + // + // The type_id of the stored type. + // + // Raises: + // + // ALREADY_EXISTS error in the case listed above. + // INVALID_ARGUMENT error, if the given type has no name, or any + // property value type is unknown. + PutArtifactType(context.Context, *PutArtifactTypeRequest) (*PutArtifactTypeResponse, error) + // Inserts or updates an ExecutionType. Please refer to PutArtifactType for + // type upsert API description. + PutExecutionType(context.Context, *PutExecutionTypeRequest) (*PutExecutionTypeResponse, error) + // Inserts or updates an ContextType. Please refer to PutArtifactType for + // type upsert API description. + PutContextType(context.Context, *PutContextTypeRequest) (*PutContextTypeResponse, error) + // Bulk inserts types atomically. + PutTypes(context.Context, *PutTypesRequest) (*PutTypesResponse, error) + // Inserts or updates artifacts in the database. + // + // If an artifact_id is specified for an artifact, it is an update. + // If an artifact_id is unspecified, it will insert a new artifact. + // For new artifacts, type must be specified. + // For old artifacts, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated artifacts will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // + // artifacts: A list of artifacts to insert or update. + // + // Returns: + // + // A list of artifact ids index-aligned with the input. + PutArtifacts(context.Context, *PutArtifactsRequest) (*PutArtifactsResponse, error) + // Inserts or updates executions in the database. + // + // If an execution_id is specified for an execution, it is an update. + // If an execution_id is unspecified, it will insert a new execution. + // For new executions, type must be specified. + // For old executions, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated executions will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // + // executions: A list of executions to insert or update. + // + // Returns: + // + // A list of execution ids index-aligned with the input. + PutExecutions(context.Context, *PutExecutionsRequest) (*PutExecutionsResponse, error) + // Inserts events in the database. + // + // The execution_id and artifact_id must already exist. + // Once created, events cannot be modified. + // AlreadyExists error will be raised if duplicated events are found. + // + // It is not guaranteed that the created or updated events will share the + // same `milliseconds_since_epoch` timestamps. + // + // Args: + // + // events: A list of events to insert or update. + PutEvents(context.Context, *PutEventsRequest) (*PutEventsResponse, error) + // Inserts or updates an Execution and its input and output artifacts and + // related contexts atomically. The `artifact_event_pairs` include the state + // changes of the Artifacts used or generated by the Execution, as well as the + // input/output Event. The `contexts` describe the associations of the + // execution and the attributions of the artifacts. + // + // If an execution_id is specified, it is an update on the corresponding + // execution, otherwise it does an insertion. + // For insertion, type must be specified. Same rule applies to artifacts + // and contexts in the request. Corresponding errors may raised. For example: + // AlreadyExists error will be raised if duplicated executions, artifacts + // or events are found. + // + // It is not guaranteed that the created or updated executions, artifacts, + // contexts and events will share the same `create_time_since_epoch`, + // `last_update_time_since_epoch`, or `milliseconds_since_epoch` timestamps. + // + // Args: + // + // execution: An execution to insert or update. + // artifact_event_pairs: Artifacts to insert or update and events to insert. + // contexts: The contexts that the execution and the artifacts belong to. + // + // Returns: + // + // An execution id and a list of artifacts and contexts ids index-aligned + // with the input. + PutExecution(context.Context, *PutExecutionRequest) (*PutExecutionResponse, error) + // Inserts or updates a lineage subgraph (i.e. a collection of event edges + // and its executions, artifacts, and related contexts) atomically. The + // `event_edges` include an Event and the indices of the corresponding + // execution and artifact from the input list of executions and artifacts. The + // `contexts` describe the associations of the Execution and the attributions + // of the Artifact. + // + // If an execution_id is specified, it is an update on the corresponding + // Execution, otherwise it does an insertion. For insertion, type must be + // specified. These rules apply to Artifacts and Contexts as well. + // Corresponding errors may be raised. For example: AlreadyExists error will + // be raised if duplicated executions, artifacts, or events are found. + // + // It is not guaranteed that the created or updated executions, artifacts, + // contexts and events will share the same `create_time_since_epoch`, + // `last_update_time_since_epoch`, or `milliseconds_since_epoch` timestamps. + // + // Args: + // + // executions: A list of executions to insert or update. + // artifacts: A list of artifacts to insert or update. + // contexts: A list of contexts to insert and/or create associations and + // attributions with. + // event_edges: A list of events to insert with the indices of the + // corresponding execution and artifact from the input lists of + // executions and artifacts. + // + // Returns: + // + // Lists of execution, artifact, and context ids index-aligned with the + // inputs. + PutLineageSubgraph(context.Context, *PutLineageSubgraphRequest) (*PutLineageSubgraphResponse, error) + // Inserts or updates contexts in database and returns a list of context ids. + // + // If an context_id is specified for a context, it is an update. + // If an context_id is unspecified, it will insert a new context. + // For new contexts, type must be specified. + // For old contexts, type must be unchanged or unspecified. + // + // It is not guaranteed that the created or updated contexts will share the + // same `create_time_since_epoch` or `last_update_time_since_epoch` + // timestamps. + // + // Args: + // + // contexts: A list of contexts to insert or update. + // + // Returns: + // + // A list of context ids index-aligned with the input. + PutContexts(context.Context, *PutContextsRequest) (*PutContextsResponse, error) + // Inserts attribution and association relationships in the database. + // The context_id, artifact_id, and execution_id must already exist. + // If the relationship exists, this call does nothing. Once added, the + // relationships cannot be modified. + // + // Args: + // + // attributions: A list of attributions to insert. + // associations: A list of associations to insert. + PutAttributionsAndAssociations(context.Context, *PutAttributionsAndAssociationsRequest) (*PutAttributionsAndAssociationsResponse, error) + // Inserts parental context relationships in the database. + // The ParentContext relationship has direction. The call fails if cycles are + // detected. + // + // Args: + // + // parent_contexts: A list of parent contexts to insert. + PutParentContexts(context.Context, *PutParentContextsRequest) (*PutParentContextsResponse, error) + // Gets an artifact type. Returns a NOT_FOUND error if the type does not + // exist. + GetArtifactType(context.Context, *GetArtifactTypeRequest) (*GetArtifactTypeResponse, error) + // Gets a list of artifact types by ID. + // If no artifact types with an ID exists, the artifact type is skipped. + GetArtifactTypesByID(context.Context, *GetArtifactTypesByIDRequest) (*GetArtifactTypesByIDResponse, error) + // Gets a list of all artifact types. + GetArtifactTypes(context.Context, *GetArtifactTypesRequest) (*GetArtifactTypesResponse, error) + // Gets an execution type, or None if it does not exist. + GetExecutionType(context.Context, *GetExecutionTypeRequest) (*GetExecutionTypeResponse, error) + // Gets a list of execution types by ID. + // If no execution types with an ID exists, the execution type is skipped. + GetExecutionTypesByID(context.Context, *GetExecutionTypesByIDRequest) (*GetExecutionTypesByIDResponse, error) + // Gets a list of all execution types. + GetExecutionTypes(context.Context, *GetExecutionTypesRequest) (*GetExecutionTypesResponse, error) + // Gets a context type. Returns a NOT_FOUND error if the type does not exist. + GetContextType(context.Context, *GetContextTypeRequest) (*GetContextTypeResponse, error) + // Gets a list of context types by ID. + // If no context types with an ID exists, the context type is skipped. + GetContextTypesByID(context.Context, *GetContextTypesByIDRequest) (*GetContextTypesByIDResponse, error) + // Gets a list of all context types. + GetContextTypes(context.Context, *GetContextTypesRequest) (*GetContextTypesResponse, error) + // Gets all the artifacts. + GetArtifacts(context.Context, *GetArtifactsRequest) (*GetArtifactsResponse, error) + // Gets all the executions. + GetExecutions(context.Context, *GetExecutionsRequest) (*GetExecutionsResponse, error) + // Gets all the contexts. + GetContexts(context.Context, *GetContextsRequest) (*GetContextsResponse, error) + // Gets all artifacts with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // + // artifact_ids: A list of artifact ids to retrieve. + // + // Returns: + // + // Artifacts with matching ids. + GetArtifactsByID(context.Context, *GetArtifactsByIDRequest) (*GetArtifactsByIDResponse, error) + // Gets all executions with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // + // execution_ids: A list of execution ids to retrieve. + GetExecutionsByID(context.Context, *GetExecutionsByIDRequest) (*GetExecutionsByIDResponse, error) + // Gets all contexts with matching ids. + // + // The result is not index-aligned: if an id is not found, it is not returned. + // + // Args: + // + // context_ids: A list of context ids to retrieve. + GetContextsByID(context.Context, *GetContextsByIDRequest) (*GetContextsByIDResponse, error) + // Gets all the artifacts of a given type. + GetArtifactsByType(context.Context, *GetArtifactsByTypeRequest) (*GetArtifactsByTypeResponse, error) + // Gets all the executions of a given type. + GetExecutionsByType(context.Context, *GetExecutionsByTypeRequest) (*GetExecutionsByTypeResponse, error) + // Gets all the contexts of a given type. + GetContextsByType(context.Context, *GetContextsByTypeRequest) (*GetContextsByTypeResponse, error) + // Gets the artifact of the given type and artifact name. + GetArtifactByTypeAndName(context.Context, *GetArtifactByTypeAndNameRequest) (*GetArtifactByTypeAndNameResponse, error) + // Gets the execution of the given type and execution name. + GetExecutionByTypeAndName(context.Context, *GetExecutionByTypeAndNameRequest) (*GetExecutionByTypeAndNameResponse, error) + // Gets the context of the given type and context name. + GetContextByTypeAndName(context.Context, *GetContextByTypeAndNameRequest) (*GetContextByTypeAndNameResponse, error) + // Gets all the artifacts with matching uris. + GetArtifactsByURI(context.Context, *GetArtifactsByURIRequest) (*GetArtifactsByURIResponse, error) + // Gets all events with matching execution ids. + GetEventsByExecutionIDs(context.Context, *GetEventsByExecutionIDsRequest) (*GetEventsByExecutionIDsResponse, error) + // Gets all events with matching artifact ids. + GetEventsByArtifactIDs(context.Context, *GetEventsByArtifactIDsRequest) (*GetEventsByArtifactIDsResponse, error) + // Gets all the artifacts with matching external ids. + GetArtifactsByExternalIds(context.Context, *GetArtifactsByExternalIdsRequest) (*GetArtifactsByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetExecutionsByExternalIds(context.Context, *GetExecutionsByExternalIdsRequest) (*GetExecutionsByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetContextsByExternalIds(context.Context, *GetContextsByExternalIdsRequest) (*GetContextsByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetArtifactTypesByExternalIds(context.Context, *GetArtifactTypesByExternalIdsRequest) (*GetArtifactTypesByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetExecutionTypesByExternalIds(context.Context, *GetExecutionTypesByExternalIdsRequest) (*GetExecutionTypesByExternalIdsResponse, error) + // Gets all the artifacts with matching external ids. + GetContextTypesByExternalIds(context.Context, *GetContextTypesByExternalIdsRequest) (*GetContextTypesByExternalIdsResponse, error) + // Gets all context that an artifact is attributed to. + GetContextsByArtifact(context.Context, *GetContextsByArtifactRequest) (*GetContextsByArtifactResponse, error) + // Gets all context that an execution is associated with. + GetContextsByExecution(context.Context, *GetContextsByExecutionRequest) (*GetContextsByExecutionResponse, error) + // Gets all parent contexts that a context is related. + GetParentContextsByContext(context.Context, *GetParentContextsByContextRequest) (*GetParentContextsByContextResponse, error) + // Gets all children contexts that a context is related. + GetChildrenContextsByContext(context.Context, *GetChildrenContextsByContextRequest) (*GetChildrenContextsByContextResponse, error) + // Batch getting all the parent contexts that a list of contexts are related. + GetParentContextsByContexts(context.Context, *GetParentContextsByContextsRequest) (*GetParentContextsByContextsResponse, error) + // Batch getting all the children contexts that a list of contexts are + // related. + GetChildrenContextsByContexts(context.Context, *GetChildrenContextsByContextsRequest) (*GetChildrenContextsByContextsResponse, error) + // Gets all direct artifacts that a context attributes to. + GetArtifactsByContext(context.Context, *GetArtifactsByContextRequest) (*GetArtifactsByContextResponse, error) + // Gets all direct executions that a context associates with. + GetExecutionsByContext(context.Context, *GetExecutionsByContextRequest) (*GetExecutionsByContextResponse, error) + // TODO(b/283852485): Deprecate GetLineageGraph API after migration to + // GetLineageSubgraph API. + // The transaction performs a constrained transitive closure and returns a + // lineage subgraph satisfying the conditions and constraints specified in + // the GetLineageGraphRequest. + GetLineageGraph(context.Context, *GetLineageGraphRequest) (*GetLineageGraphResponse, error) + // Gets a lineage subgraph by performing graph traversal from a list of + // interested nodes. + // A lineage subgraph without node details (e.g., external_id, properties) + // will be returned. + GetLineageSubgraph(context.Context, *GetLineageSubgraphRequest) (*GetLineageSubgraphResponse, error) + mustEmbedUnimplementedMetadataStoreServiceServer() +} + +// UnimplementedMetadataStoreServiceServer must be embedded to have forward compatible implementations. +type UnimplementedMetadataStoreServiceServer struct { +} + +func (UnimplementedMetadataStoreServiceServer) PutArtifactType(context.Context, *PutArtifactTypeRequest) (*PutArtifactTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutArtifactType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutExecutionType(context.Context, *PutExecutionTypeRequest) (*PutExecutionTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutExecutionType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutContextType(context.Context, *PutContextTypeRequest) (*PutContextTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutContextType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutTypes(context.Context, *PutTypesRequest) (*PutTypesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutTypes not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutArtifacts(context.Context, *PutArtifactsRequest) (*PutArtifactsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutArtifacts not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutExecutions(context.Context, *PutExecutionsRequest) (*PutExecutionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutExecutions not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutEvents(context.Context, *PutEventsRequest) (*PutEventsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutEvents not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutExecution(context.Context, *PutExecutionRequest) (*PutExecutionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutExecution not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutLineageSubgraph(context.Context, *PutLineageSubgraphRequest) (*PutLineageSubgraphResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutLineageSubgraph not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutContexts(context.Context, *PutContextsRequest) (*PutContextsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutContexts not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutAttributionsAndAssociations(context.Context, *PutAttributionsAndAssociationsRequest) (*PutAttributionsAndAssociationsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutAttributionsAndAssociations not implemented") +} +func (UnimplementedMetadataStoreServiceServer) PutParentContexts(context.Context, *PutParentContextsRequest) (*PutParentContextsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method PutParentContexts not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactType(context.Context, *GetArtifactTypeRequest) (*GetArtifactTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactTypesByID(context.Context, *GetArtifactTypesByIDRequest) (*GetArtifactTypesByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactTypesByID not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactTypes(context.Context, *GetArtifactTypesRequest) (*GetArtifactTypesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactTypes not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionType(context.Context, *GetExecutionTypeRequest) (*GetExecutionTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionTypesByID(context.Context, *GetExecutionTypesByIDRequest) (*GetExecutionTypesByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionTypesByID not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionTypes(context.Context, *GetExecutionTypesRequest) (*GetExecutionTypesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionTypes not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextType(context.Context, *GetContextTypeRequest) (*GetContextTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextTypesByID(context.Context, *GetContextTypesByIDRequest) (*GetContextTypesByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextTypesByID not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextTypes(context.Context, *GetContextTypesRequest) (*GetContextTypesResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextTypes not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifacts(context.Context, *GetArtifactsRequest) (*GetArtifactsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifacts not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutions(context.Context, *GetExecutionsRequest) (*GetExecutionsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutions not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContexts(context.Context, *GetContextsRequest) (*GetContextsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContexts not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactsByID(context.Context, *GetArtifactsByIDRequest) (*GetArtifactsByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactsByID not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionsByID(context.Context, *GetExecutionsByIDRequest) (*GetExecutionsByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionsByID not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextsByID(context.Context, *GetContextsByIDRequest) (*GetContextsByIDResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextsByID not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactsByType(context.Context, *GetArtifactsByTypeRequest) (*GetArtifactsByTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactsByType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionsByType(context.Context, *GetExecutionsByTypeRequest) (*GetExecutionsByTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionsByType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextsByType(context.Context, *GetContextsByTypeRequest) (*GetContextsByTypeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextsByType not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactByTypeAndName(context.Context, *GetArtifactByTypeAndNameRequest) (*GetArtifactByTypeAndNameResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactByTypeAndName not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionByTypeAndName(context.Context, *GetExecutionByTypeAndNameRequest) (*GetExecutionByTypeAndNameResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionByTypeAndName not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextByTypeAndName(context.Context, *GetContextByTypeAndNameRequest) (*GetContextByTypeAndNameResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextByTypeAndName not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactsByURI(context.Context, *GetArtifactsByURIRequest) (*GetArtifactsByURIResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactsByURI not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetEventsByExecutionIDs(context.Context, *GetEventsByExecutionIDsRequest) (*GetEventsByExecutionIDsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetEventsByExecutionIDs not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetEventsByArtifactIDs(context.Context, *GetEventsByArtifactIDsRequest) (*GetEventsByArtifactIDsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetEventsByArtifactIDs not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactsByExternalIds(context.Context, *GetArtifactsByExternalIdsRequest) (*GetArtifactsByExternalIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactsByExternalIds not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionsByExternalIds(context.Context, *GetExecutionsByExternalIdsRequest) (*GetExecutionsByExternalIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionsByExternalIds not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextsByExternalIds(context.Context, *GetContextsByExternalIdsRequest) (*GetContextsByExternalIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextsByExternalIds not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactTypesByExternalIds(context.Context, *GetArtifactTypesByExternalIdsRequest) (*GetArtifactTypesByExternalIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactTypesByExternalIds not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionTypesByExternalIds(context.Context, *GetExecutionTypesByExternalIdsRequest) (*GetExecutionTypesByExternalIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionTypesByExternalIds not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextTypesByExternalIds(context.Context, *GetContextTypesByExternalIdsRequest) (*GetContextTypesByExternalIdsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextTypesByExternalIds not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextsByArtifact(context.Context, *GetContextsByArtifactRequest) (*GetContextsByArtifactResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextsByArtifact not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetContextsByExecution(context.Context, *GetContextsByExecutionRequest) (*GetContextsByExecutionResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetContextsByExecution not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetParentContextsByContext(context.Context, *GetParentContextsByContextRequest) (*GetParentContextsByContextResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetParentContextsByContext not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetChildrenContextsByContext(context.Context, *GetChildrenContextsByContextRequest) (*GetChildrenContextsByContextResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChildrenContextsByContext not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetParentContextsByContexts(context.Context, *GetParentContextsByContextsRequest) (*GetParentContextsByContextsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetParentContextsByContexts not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetChildrenContextsByContexts(context.Context, *GetChildrenContextsByContextsRequest) (*GetChildrenContextsByContextsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChildrenContextsByContexts not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetArtifactsByContext(context.Context, *GetArtifactsByContextRequest) (*GetArtifactsByContextResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetArtifactsByContext not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetExecutionsByContext(context.Context, *GetExecutionsByContextRequest) (*GetExecutionsByContextResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetExecutionsByContext not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetLineageGraph(context.Context, *GetLineageGraphRequest) (*GetLineageGraphResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLineageGraph not implemented") +} +func (UnimplementedMetadataStoreServiceServer) GetLineageSubgraph(context.Context, *GetLineageSubgraphRequest) (*GetLineageSubgraphResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetLineageSubgraph not implemented") +} +func (UnimplementedMetadataStoreServiceServer) mustEmbedUnimplementedMetadataStoreServiceServer() {} + +// UnsafeMetadataStoreServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to MetadataStoreServiceServer will +// result in compilation errors. +type UnsafeMetadataStoreServiceServer interface { + mustEmbedUnimplementedMetadataStoreServiceServer() +} + +func RegisterMetadataStoreServiceServer(s grpc.ServiceRegistrar, srv MetadataStoreServiceServer) { + s.RegisterService(&MetadataStoreService_ServiceDesc, srv) +} + +func _MetadataStoreService_PutArtifactType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutArtifactTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutArtifactType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutArtifactType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutArtifactType(ctx, req.(*PutArtifactTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutExecutionType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutExecutionTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutExecutionType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutExecutionType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutExecutionType(ctx, req.(*PutExecutionTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutContextType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutContextTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutContextType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutContextType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutContextType(ctx, req.(*PutContextTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutTypes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutTypesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutTypes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutTypes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutTypes(ctx, req.(*PutTypesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutArtifacts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutArtifactsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutArtifacts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutArtifacts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutArtifacts(ctx, req.(*PutArtifactsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutExecutions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutExecutionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutExecutions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutExecutions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutExecutions(ctx, req.(*PutExecutionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutEvents_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutEventsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutEvents(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutEvents_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutEvents(ctx, req.(*PutEventsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutExecution_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutExecutionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutExecution(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutExecution_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutExecution(ctx, req.(*PutExecutionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutLineageSubgraph_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutLineageSubgraphRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutLineageSubgraph(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutLineageSubgraph_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutLineageSubgraph(ctx, req.(*PutLineageSubgraphRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutContexts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutContextsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutContexts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutContexts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutContexts(ctx, req.(*PutContextsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutAttributionsAndAssociations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutAttributionsAndAssociationsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutAttributionsAndAssociations(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutAttributionsAndAssociations_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutAttributionsAndAssociations(ctx, req.(*PutAttributionsAndAssociationsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_PutParentContexts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(PutParentContextsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).PutParentContexts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_PutParentContexts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).PutParentContexts(ctx, req.(*PutParentContextsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactType(ctx, req.(*GetArtifactTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactTypesByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactTypesByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactTypesByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactTypesByID_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactTypesByID(ctx, req.(*GetArtifactTypesByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactTypes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactTypesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactTypes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactTypes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactTypes(ctx, req.(*GetArtifactTypesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionType(ctx, req.(*GetExecutionTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionTypesByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionTypesByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionTypesByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionTypesByID_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionTypesByID(ctx, req.(*GetExecutionTypesByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionTypes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionTypesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionTypes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionTypes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionTypes(ctx, req.(*GetExecutionTypesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextType(ctx, req.(*GetContextTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextTypesByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextTypesByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextTypesByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextTypesByID_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextTypesByID(ctx, req.(*GetContextTypesByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextTypes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextTypesRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextTypes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextTypes_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextTypes(ctx, req.(*GetContextTypesRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifacts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifacts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifacts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifacts(ctx, req.(*GetArtifactsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutions_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutions(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutions_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutions(ctx, req.(*GetExecutionsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContexts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContexts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContexts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContexts(ctx, req.(*GetContextsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactsByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactsByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactsByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactsByID_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactsByID(ctx, req.(*GetArtifactsByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionsByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionsByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionsByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionsByID_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionsByID(ctx, req.(*GetExecutionsByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextsByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextsByIDRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextsByID(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextsByID_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextsByID(ctx, req.(*GetContextsByIDRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactsByType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactsByTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactsByType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactsByType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactsByType(ctx, req.(*GetArtifactsByTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionsByType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionsByTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionsByType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionsByType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionsByType(ctx, req.(*GetExecutionsByTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextsByType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextsByTypeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextsByType(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextsByType_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextsByType(ctx, req.(*GetContextsByTypeRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactByTypeAndName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactByTypeAndNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactByTypeAndName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactByTypeAndName_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactByTypeAndName(ctx, req.(*GetArtifactByTypeAndNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionByTypeAndName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionByTypeAndNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionByTypeAndName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionByTypeAndName_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionByTypeAndName(ctx, req.(*GetExecutionByTypeAndNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextByTypeAndName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextByTypeAndNameRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextByTypeAndName(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextByTypeAndName_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextByTypeAndName(ctx, req.(*GetContextByTypeAndNameRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactsByURI_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactsByURIRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactsByURI(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactsByURI_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactsByURI(ctx, req.(*GetArtifactsByURIRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetEventsByExecutionIDs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetEventsByExecutionIDsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetEventsByExecutionIDs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetEventsByExecutionIDs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetEventsByExecutionIDs(ctx, req.(*GetEventsByExecutionIDsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetEventsByArtifactIDs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetEventsByArtifactIDsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetEventsByArtifactIDs(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetEventsByArtifactIDs_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetEventsByArtifactIDs(ctx, req.(*GetEventsByArtifactIDsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactsByExternalIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactsByExternalIdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactsByExternalIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactsByExternalIds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactsByExternalIds(ctx, req.(*GetArtifactsByExternalIdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionsByExternalIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionsByExternalIdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionsByExternalIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionsByExternalIds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionsByExternalIds(ctx, req.(*GetExecutionsByExternalIdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextsByExternalIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextsByExternalIdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextsByExternalIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextsByExternalIds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextsByExternalIds(ctx, req.(*GetContextsByExternalIdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactTypesByExternalIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactTypesByExternalIdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactTypesByExternalIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactTypesByExternalIds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactTypesByExternalIds(ctx, req.(*GetArtifactTypesByExternalIdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionTypesByExternalIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionTypesByExternalIdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionTypesByExternalIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionTypesByExternalIds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionTypesByExternalIds(ctx, req.(*GetExecutionTypesByExternalIdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextTypesByExternalIds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextTypesByExternalIdsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextTypesByExternalIds(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextTypesByExternalIds_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextTypesByExternalIds(ctx, req.(*GetContextTypesByExternalIdsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextsByArtifact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextsByArtifactRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextsByArtifact(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextsByArtifact_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextsByArtifact(ctx, req.(*GetContextsByArtifactRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetContextsByExecution_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetContextsByExecutionRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetContextsByExecution(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetContextsByExecution_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetContextsByExecution(ctx, req.(*GetContextsByExecutionRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetParentContextsByContext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetParentContextsByContextRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetParentContextsByContext(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetParentContextsByContext_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetParentContextsByContext(ctx, req.(*GetParentContextsByContextRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetChildrenContextsByContext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetChildrenContextsByContextRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetChildrenContextsByContext(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetChildrenContextsByContext_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetChildrenContextsByContext(ctx, req.(*GetChildrenContextsByContextRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetParentContextsByContexts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetParentContextsByContextsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetParentContextsByContexts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetParentContextsByContexts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetParentContextsByContexts(ctx, req.(*GetParentContextsByContextsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetChildrenContextsByContexts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetChildrenContextsByContextsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetChildrenContextsByContexts(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetChildrenContextsByContexts_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetChildrenContextsByContexts(ctx, req.(*GetChildrenContextsByContextsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetArtifactsByContext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetArtifactsByContextRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetArtifactsByContext(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetArtifactsByContext_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetArtifactsByContext(ctx, req.(*GetArtifactsByContextRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetExecutionsByContext_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetExecutionsByContextRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetExecutionsByContext(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetExecutionsByContext_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetExecutionsByContext(ctx, req.(*GetExecutionsByContextRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetLineageGraph_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLineageGraphRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetLineageGraph(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetLineageGraph_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetLineageGraph(ctx, req.(*GetLineageGraphRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _MetadataStoreService_GetLineageSubgraph_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetLineageSubgraphRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MetadataStoreServiceServer).GetLineageSubgraph(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: MetadataStoreService_GetLineageSubgraph_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MetadataStoreServiceServer).GetLineageSubgraph(ctx, req.(*GetLineageSubgraphRequest)) + } + return interceptor(ctx, in, info, handler) +} + +// MetadataStoreService_ServiceDesc is the grpc.ServiceDesc for MetadataStoreService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var MetadataStoreService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "ml_metadata.MetadataStoreService", + HandlerType: (*MetadataStoreServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "PutArtifactType", + Handler: _MetadataStoreService_PutArtifactType_Handler, + }, + { + MethodName: "PutExecutionType", + Handler: _MetadataStoreService_PutExecutionType_Handler, + }, + { + MethodName: "PutContextType", + Handler: _MetadataStoreService_PutContextType_Handler, + }, + { + MethodName: "PutTypes", + Handler: _MetadataStoreService_PutTypes_Handler, + }, + { + MethodName: "PutArtifacts", + Handler: _MetadataStoreService_PutArtifacts_Handler, + }, + { + MethodName: "PutExecutions", + Handler: _MetadataStoreService_PutExecutions_Handler, + }, + { + MethodName: "PutEvents", + Handler: _MetadataStoreService_PutEvents_Handler, + }, + { + MethodName: "PutExecution", + Handler: _MetadataStoreService_PutExecution_Handler, + }, + { + MethodName: "PutLineageSubgraph", + Handler: _MetadataStoreService_PutLineageSubgraph_Handler, + }, + { + MethodName: "PutContexts", + Handler: _MetadataStoreService_PutContexts_Handler, + }, + { + MethodName: "PutAttributionsAndAssociations", + Handler: _MetadataStoreService_PutAttributionsAndAssociations_Handler, + }, + { + MethodName: "PutParentContexts", + Handler: _MetadataStoreService_PutParentContexts_Handler, + }, + { + MethodName: "GetArtifactType", + Handler: _MetadataStoreService_GetArtifactType_Handler, + }, + { + MethodName: "GetArtifactTypesByID", + Handler: _MetadataStoreService_GetArtifactTypesByID_Handler, + }, + { + MethodName: "GetArtifactTypes", + Handler: _MetadataStoreService_GetArtifactTypes_Handler, + }, + { + MethodName: "GetExecutionType", + Handler: _MetadataStoreService_GetExecutionType_Handler, + }, + { + MethodName: "GetExecutionTypesByID", + Handler: _MetadataStoreService_GetExecutionTypesByID_Handler, + }, + { + MethodName: "GetExecutionTypes", + Handler: _MetadataStoreService_GetExecutionTypes_Handler, + }, + { + MethodName: "GetContextType", + Handler: _MetadataStoreService_GetContextType_Handler, + }, + { + MethodName: "GetContextTypesByID", + Handler: _MetadataStoreService_GetContextTypesByID_Handler, + }, + { + MethodName: "GetContextTypes", + Handler: _MetadataStoreService_GetContextTypes_Handler, + }, + { + MethodName: "GetArtifacts", + Handler: _MetadataStoreService_GetArtifacts_Handler, + }, + { + MethodName: "GetExecutions", + Handler: _MetadataStoreService_GetExecutions_Handler, + }, + { + MethodName: "GetContexts", + Handler: _MetadataStoreService_GetContexts_Handler, + }, + { + MethodName: "GetArtifactsByID", + Handler: _MetadataStoreService_GetArtifactsByID_Handler, + }, + { + MethodName: "GetExecutionsByID", + Handler: _MetadataStoreService_GetExecutionsByID_Handler, + }, + { + MethodName: "GetContextsByID", + Handler: _MetadataStoreService_GetContextsByID_Handler, + }, + { + MethodName: "GetArtifactsByType", + Handler: _MetadataStoreService_GetArtifactsByType_Handler, + }, + { + MethodName: "GetExecutionsByType", + Handler: _MetadataStoreService_GetExecutionsByType_Handler, + }, + { + MethodName: "GetContextsByType", + Handler: _MetadataStoreService_GetContextsByType_Handler, + }, + { + MethodName: "GetArtifactByTypeAndName", + Handler: _MetadataStoreService_GetArtifactByTypeAndName_Handler, + }, + { + MethodName: "GetExecutionByTypeAndName", + Handler: _MetadataStoreService_GetExecutionByTypeAndName_Handler, + }, + { + MethodName: "GetContextByTypeAndName", + Handler: _MetadataStoreService_GetContextByTypeAndName_Handler, + }, + { + MethodName: "GetArtifactsByURI", + Handler: _MetadataStoreService_GetArtifactsByURI_Handler, + }, + { + MethodName: "GetEventsByExecutionIDs", + Handler: _MetadataStoreService_GetEventsByExecutionIDs_Handler, + }, + { + MethodName: "GetEventsByArtifactIDs", + Handler: _MetadataStoreService_GetEventsByArtifactIDs_Handler, + }, + { + MethodName: "GetArtifactsByExternalIds", + Handler: _MetadataStoreService_GetArtifactsByExternalIds_Handler, + }, + { + MethodName: "GetExecutionsByExternalIds", + Handler: _MetadataStoreService_GetExecutionsByExternalIds_Handler, + }, + { + MethodName: "GetContextsByExternalIds", + Handler: _MetadataStoreService_GetContextsByExternalIds_Handler, + }, + { + MethodName: "GetArtifactTypesByExternalIds", + Handler: _MetadataStoreService_GetArtifactTypesByExternalIds_Handler, + }, + { + MethodName: "GetExecutionTypesByExternalIds", + Handler: _MetadataStoreService_GetExecutionTypesByExternalIds_Handler, + }, + { + MethodName: "GetContextTypesByExternalIds", + Handler: _MetadataStoreService_GetContextTypesByExternalIds_Handler, + }, + { + MethodName: "GetContextsByArtifact", + Handler: _MetadataStoreService_GetContextsByArtifact_Handler, + }, + { + MethodName: "GetContextsByExecution", + Handler: _MetadataStoreService_GetContextsByExecution_Handler, + }, + { + MethodName: "GetParentContextsByContext", + Handler: _MetadataStoreService_GetParentContextsByContext_Handler, + }, + { + MethodName: "GetChildrenContextsByContext", + Handler: _MetadataStoreService_GetChildrenContextsByContext_Handler, + }, + { + MethodName: "GetParentContextsByContexts", + Handler: _MetadataStoreService_GetParentContextsByContexts_Handler, + }, + { + MethodName: "GetChildrenContextsByContexts", + Handler: _MetadataStoreService_GetChildrenContextsByContexts_Handler, + }, + { + MethodName: "GetArtifactsByContext", + Handler: _MetadataStoreService_GetArtifactsByContext_Handler, + }, + { + MethodName: "GetExecutionsByContext", + Handler: _MetadataStoreService_GetExecutionsByContext_Handler, + }, + { + MethodName: "GetLineageGraph", + Handler: _MetadataStoreService_GetLineageGraph_Handler, + }, + { + MethodName: "GetLineageSubgraph", + Handler: _MetadataStoreService_GetLineageSubgraph_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ml_metadata/proto/metadata_store_service.proto", +} diff --git a/model/db/artifact.gen.go b/pkg/model/db/artifact.gen.go similarity index 100% rename from model/db/artifact.gen.go rename to pkg/model/db/artifact.gen.go diff --git a/model/db/artifactproperty.gen.go b/pkg/model/db/artifactproperty.gen.go similarity index 100% rename from model/db/artifactproperty.gen.go rename to pkg/model/db/artifactproperty.gen.go diff --git a/model/db/association.gen.go b/pkg/model/db/association.gen.go similarity index 100% rename from model/db/association.gen.go rename to pkg/model/db/association.gen.go diff --git a/model/db/attribution.gen.go b/pkg/model/db/attribution.gen.go similarity index 100% rename from model/db/attribution.gen.go rename to pkg/model/db/attribution.gen.go diff --git a/model/db/context.gen.go b/pkg/model/db/context.gen.go similarity index 85% rename from model/db/context.gen.go rename to pkg/model/db/context.gen.go index ea6c7559..a1bf7673 100644 --- a/model/db/context.gen.go +++ b/pkg/model/db/context.gen.go @@ -17,13 +17,13 @@ type Context struct { // relationships Properties []ContextProperty - ContextType Type `gorm:"foreignKey:TypeID;references:ID"` + ContextType Type `gorm:"foreignKey:TypeID;references:ID"` Attributions []Attribution `gorm:"foreignKey:ContextID;references:ID"` Associations []Association `gorm:"foreignKey:ContextID;references:ID"` // self-reference for context graphs - Parents []ParentContext `gorm:"foreignKey:ContextID;references:ID"` - Children []ParentContext `gorm:"foreignKey:ParentContextID;references:ID"` + Parents []ParentContext `gorm:"foreignKey:ContextID;references:ID"` + Children []ParentContext `gorm:"foreignKey:ParentContextID;references:ID"` } // TableName Context's table name diff --git a/model/db/contextproperty.gen.go b/pkg/model/db/contextproperty.gen.go similarity index 100% rename from model/db/contextproperty.gen.go rename to pkg/model/db/contextproperty.gen.go diff --git a/model/db/event.gen.go b/pkg/model/db/event.gen.go similarity index 97% rename from model/db/event.gen.go rename to pkg/model/db/event.gen.go index 7c436960..8a113f33 100644 --- a/model/db/event.gen.go +++ b/pkg/model/db/event.gen.go @@ -15,7 +15,7 @@ type Event struct { MillisecondsSinceEpoch *int64 `gorm:"autoCreateTime:milli;column:milliseconds_since_epoch;not null" json:"-"` // relationships - Artifact Artifact + Artifact Artifact Execution Execution } diff --git a/model/db/eventpath.gen.go b/pkg/model/db/eventpath.gen.go similarity index 100% rename from model/db/eventpath.gen.go rename to pkg/model/db/eventpath.gen.go diff --git a/model/db/execution.gen.go b/pkg/model/db/execution.gen.go similarity index 93% rename from model/db/execution.gen.go rename to pkg/model/db/execution.gen.go index f97fe896..f12c1bfe 100644 --- a/model/db/execution.gen.go +++ b/pkg/model/db/execution.gen.go @@ -18,9 +18,9 @@ type Execution struct { // relationships Properties []ExecutionProperty - ExecutionType Type `gorm:"foreignKey:TypeID;references:ID"` + ExecutionType Type `gorm:"foreignKey:TypeID;references:ID"` Associations []Association `gorm:"foreignKey:ExecutionID;references:ID"` - Events []Event + Events []Event } // TableName Execution's table name diff --git a/model/db/executionproperty.gen.go b/pkg/model/db/executionproperty.gen.go similarity index 100% rename from model/db/executionproperty.gen.go rename to pkg/model/db/executionproperty.gen.go diff --git a/model/db/mlmdenv.gen.go b/pkg/model/db/mlmdenv.gen.go similarity index 100% rename from model/db/mlmdenv.gen.go rename to pkg/model/db/mlmdenv.gen.go diff --git a/model/db/parentcontext.gen.go b/pkg/model/db/parentcontext.gen.go similarity index 100% rename from model/db/parentcontext.gen.go rename to pkg/model/db/parentcontext.gen.go diff --git a/model/db/parenttype.gen.go b/pkg/model/db/parenttype.gen.go similarity index 100% rename from model/db/parenttype.gen.go rename to pkg/model/db/parenttype.gen.go diff --git a/model/db/type.gen.go b/pkg/model/db/type.gen.go similarity index 100% rename from model/db/type.gen.go rename to pkg/model/db/type.gen.go diff --git a/model/db/typeproperty.gen.go b/pkg/model/db/typeproperty.gen.go similarity index 100% rename from model/db/typeproperty.gen.go rename to pkg/model/db/typeproperty.gen.go diff --git a/model/graph/models_gen.go b/pkg/model/graph/models_gen.go similarity index 100% rename from model/graph/models_gen.go rename to pkg/model/graph/models_gen.go diff --git a/model/library/metadata_library.go b/pkg/model/library/metadata_library.go similarity index 95% rename from model/library/metadata_library.go rename to pkg/model/library/metadata_library.go index 757d8609..b5efaac6 100644 --- a/model/library/metadata_library.go +++ b/pkg/model/library/metadata_library.go @@ -1,6 +1,8 @@ package library -import "github.com/opendatahub-io/model-registry/ml_metadata/proto" +import ( + "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" +) //go:generate go-enum -type=PropertyType diff --git a/model/library/propertytype_enum.go b/pkg/model/library/propertytype_enum.go similarity index 100% rename from model/library/propertytype_enum.go rename to pkg/model/library/propertytype_enum.go diff --git a/server/db_context.go b/pkg/server/db_context.go similarity index 100% rename from server/db_context.go rename to pkg/server/db_context.go diff --git a/server/graph/base-schema.resolvers.go b/pkg/server/graph/base-schema.resolvers.go similarity index 92% rename from server/graph/base-schema.resolvers.go rename to pkg/server/graph/base-schema.resolvers.go index 6eff0706..94e63bfd 100644 --- a/server/graph/base-schema.resolvers.go +++ b/pkg/server/graph/base-schema.resolvers.go @@ -7,7 +7,7 @@ package graph import ( "context" - "github.com/opendatahub-io/model-registry/model/graph" + "github.com/opendatahub-io/model-registry/pkg/model/graph" ) // Type is the resolver for the type field. diff --git a/server/graph/generated.go b/pkg/server/graph/generated.go similarity index 97% rename from server/graph/generated.go rename to pkg/server/graph/generated.go index dba31a39..2cada429 100644 --- a/server/graph/generated.go +++ b/pkg/server/graph/generated.go @@ -13,7 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/introspection" - "github.com/opendatahub-io/model-registry/model/graph" + "github.com/opendatahub-io/model-registry/pkg/model/graph" gqlparser "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" ) @@ -1618,7 +1618,7 @@ func (ec *executionContext) introspectType(name string) (*introspection.Type, er } var sources = []*ast.Source{ - {Name: "../../api/graphql/base-schema.graphqls", Input: `type Artifact { + {Name: "../../../api/graphql/base-schema.graphqls", Input: `type Artifact { id: ID typeId: ID! uri: String! @@ -1794,7 +1794,7 @@ type ExecutionType implements ExecutionTypeInterface & Type { properties: [TypeProperty!] } `, BuiltIn: false}, - {Name: "../../api/graphql/ml-metadata.graphqls", Input: `type MlmdDataset implements ArtifactTypeInterface & Type { + {Name: "../../../api/graphql/ml-metadata.graphqls", Input: `type MlmdDataset implements ArtifactTypeInterface & Type { id: ID name: String! version: String! @@ -1894,7 +1894,7 @@ type MlmdDeploy implements ExecutionTypeInterface & Type { properties: [TypeProperty!] } `, BuiltIn: false}, - {Name: "../../api/graphql/schema.graphqls", Input: `input TypeFilter { + {Name: "../../../api/graphql/schema.graphqls", Input: `input TypeFilter { ids: [ID!] names: [String!] versions: [String!] @@ -1933,7 +1933,7 @@ func (ec *executionContext) field_Artifact_type_args(ctx context.Context, rawArg var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -1963,7 +1963,7 @@ func (ec *executionContext) field_Query_artifactTypes_args(ctx context.Context, var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -1978,7 +1978,7 @@ func (ec *executionContext) field_Query_artifacts_args(ctx context.Context, rawA var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -1993,7 +1993,7 @@ func (ec *executionContext) field_Query_contextTypes_args(ctx context.Context, r var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2008,7 +2008,7 @@ func (ec *executionContext) field_Query_contexts_args(ctx context.Context, rawAr var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2023,7 +2023,7 @@ func (ec *executionContext) field_Query_executionTypes_args(ctx context.Context, var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2038,7 +2038,7 @@ func (ec *executionContext) field_Query_executions_args(ctx context.Context, raw var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2053,7 +2053,7 @@ func (ec *executionContext) field_Query_mlmdDataset_args(ctx context.Context, ra var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2068,7 +2068,7 @@ func (ec *executionContext) field_Query_types_args(ctx context.Context, rawArgs var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2489,7 +2489,7 @@ func (ec *executionContext) _Artifact_type(ctx context.Context, field graphql.Co } res := resTmp.(*graph.ArtifactType) fc.Result = res - return ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) + return ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Artifact_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2557,7 +2557,7 @@ func (ec *executionContext) _Artifact_properties(ctx context.Context, field grap } res := resTmp.([]*graph.ArtifactProperty) fc.Result = res - return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Artifact_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2737,7 +2737,7 @@ func (ec *executionContext) _ArtifactProperty_propertyValue(ctx context.Context, } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3036,7 +3036,7 @@ func (ec *executionContext) _ArtifactType_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ArtifactType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3390,7 +3390,7 @@ func (ec *executionContext) _Context_type(ctx context.Context, field graphql.Col } res := resTmp.(*graph.ContextType) fc.Result = res - return ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) + return ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3447,7 +3447,7 @@ func (ec *executionContext) _Context_parent(ctx context.Context, field graphql.C } res := resTmp.(*graph.Context) fc.Result = res - return ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3514,7 +3514,7 @@ func (ec *executionContext) _Context_children(ctx context.Context, field graphql } res := resTmp.([]*graph.Context) fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_children(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3581,7 +3581,7 @@ func (ec *executionContext) _Context_attributions(ctx context.Context, field gra } res := resTmp.([]*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_attributions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3644,7 +3644,7 @@ func (ec *executionContext) _Context_associations(ctx context.Context, field gra } res := resTmp.([]*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_associations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3705,7 +3705,7 @@ func (ec *executionContext) _Context_properties(ctx context.Context, field graph } res := resTmp.([]*graph.ContextProperty) fc.Result = res - return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3888,7 +3888,7 @@ func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4187,7 +4187,7 @@ func (ec *executionContext) _ContextType_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4453,7 +4453,7 @@ func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.C } res := resTmp.(*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Event_artifact(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4516,7 +4516,7 @@ func (ec *executionContext) _Event_execution(ctx context.Context, field graphql. } res := resTmp.(*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) + return ec.marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Event_execution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5102,7 +5102,7 @@ func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.C } res := resTmp.(*graph.ExecutionType) fc.Result = res - return ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) + return ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Execution_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5163,7 +5163,7 @@ func (ec *executionContext) _Execution_properties(ctx context.Context, field gra } res := resTmp.([]*graph.ExecutionProperty) fc.Result = res - return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Execution_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5346,7 +5346,7 @@ func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5733,7 +5733,7 @@ func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6084,7 +6084,7 @@ func (ec *executionContext) _MlmdDataset_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdDataset_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6479,7 +6479,7 @@ func (ec *executionContext) _MlmdDeploy_properties(ctx context.Context, field gr } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdDeploy_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6874,7 +6874,7 @@ func (ec *executionContext) _MlmdEvaluate_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdEvaluate_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7181,7 +7181,7 @@ func (ec *executionContext) _MlmdMetrics_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdMetrics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7488,7 +7488,7 @@ func (ec *executionContext) _MlmdModel_properties(ctx context.Context, field gra } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdModel_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7883,7 +7883,7 @@ func (ec *executionContext) _MlmdProcess_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdProcess_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8190,7 +8190,7 @@ func (ec *executionContext) _MlmdStatistics_properties(ctx context.Context, fiel } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdStatistics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8585,7 +8585,7 @@ func (ec *executionContext) _MlmdTrain_properties(ctx context.Context, field gra } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdTrain_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8980,7 +8980,7 @@ func (ec *executionContext) _MlmdTransform_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdTransform_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9029,7 +9029,7 @@ func (ec *executionContext) _Query_types(ctx context.Context, field graphql.Coll } res := resTmp.([]graph.Type) fc.Result = res - return ec.marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) + return ec.marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9081,7 +9081,7 @@ func (ec *executionContext) _Query_artifactTypes(ctx context.Context, field grap } res := resTmp.([]*graph.ArtifactType) fc.Result = res - return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) + return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_artifactTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9149,7 +9149,7 @@ func (ec *executionContext) _Query_contextTypes(ctx context.Context, field graph } res := resTmp.([]*graph.ContextType) fc.Result = res - return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) + return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_contextTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9217,7 +9217,7 @@ func (ec *executionContext) _Query_executionTypes(ctx context.Context, field gra } res := resTmp.([]*graph.ExecutionType) fc.Result = res - return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) + return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_executionTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9289,7 +9289,7 @@ func (ec *executionContext) _Query_artifacts(ctx context.Context, field graphql. } res := resTmp.([]*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_artifacts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9363,7 +9363,7 @@ func (ec *executionContext) _Query_contexts(ctx context.Context, field graphql.C } res := resTmp.([]*graph.Context) fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_contexts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9441,7 +9441,7 @@ func (ec *executionContext) _Query_executions(ctx context.Context, field graphql } res := resTmp.([]*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_executions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9513,7 +9513,7 @@ func (ec *executionContext) _Query_events(ctx context.Context, field graphql.Col } res := resTmp.([]*graph.Event) fc.Result = res - return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) + return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9570,7 +9570,7 @@ func (ec *executionContext) _Query_mlmdDataset(ctx context.Context, field graphq } res := resTmp.([]*graph.MlmdDataset) fc.Result = res - return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) + return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_mlmdDataset(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -14112,7 +14112,7 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o // region ***************************** type.gotpl ***************************** -func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14122,7 +14122,7 @@ func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑio return ec._Artifact(ctx, sel, v) } -func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14132,11 +14132,11 @@ func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatah return ec._ArtifactProperty(ctx, sel, v) } -func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { return ec._ArtifactType(ctx, sel, &v) } -func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14161,7 +14161,7 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14171,7 +14171,7 @@ func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑio return ec._Context(ctx, sel, v) } -func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { +func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14181,7 +14181,7 @@ func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahu return ec._ContextProperty(ctx, sel, v) } -func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { +func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14191,7 +14191,7 @@ func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑ return ec._ContextType(ctx, sel, v) } -func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { +func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14201,7 +14201,7 @@ func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋm return ec._Event(ctx, sel, v) } -func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14211,7 +14211,7 @@ func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑio return ec._Execution(ctx, sel, v) } -func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { +func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14221,7 +14221,7 @@ func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendata return ec._ExecutionProperty(ctx, sel, v) } -func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { +func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14276,7 +14276,7 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return res } -func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { +func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14301,7 +14301,7 @@ func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.S return res } -func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { +func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14311,7 +14311,7 @@ func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodel return ec._Type(ctx, sel, v) } -func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { +func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14321,7 +14321,7 @@ func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahub return ec._TypeProperty(ctx, sel, v) } -func (ec *executionContext) marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { +func (ec *executionContext) marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14584,7 +14584,7 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a return res } -func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14611,7 +14611,7 @@ func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑ if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14631,14 +14631,14 @@ func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑ return ret } -func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Artifact(ctx, sel, v) } -func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { +func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14665,7 +14665,7 @@ func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopenda if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14685,7 +14685,7 @@ func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopenda return ret } -func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14712,7 +14712,7 @@ func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahu if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14758,7 +14758,7 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return res } -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14785,7 +14785,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14799,7 +14799,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi return ret } -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14826,7 +14826,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14846,14 +14846,14 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi return ret } -func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Context(ctx, sel, v) } -func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { +func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14880,7 +14880,7 @@ func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendat if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14900,7 +14900,7 @@ func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendat return ret } -func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { +func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14927,7 +14927,7 @@ func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahub if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) + ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14947,7 +14947,7 @@ func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahub return ret } -func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { +func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14974,7 +14974,7 @@ func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑio if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) + ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14994,7 +14994,7 @@ func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑio return ret } -func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15021,7 +15021,7 @@ func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahub if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) + ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15041,14 +15041,14 @@ func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahub return ret } -func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Execution(ctx, sel, v) } -func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { +func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15075,7 +15075,7 @@ func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopend if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15095,7 +15095,7 @@ func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopend return ret } -func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { +func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15122,7 +15122,7 @@ func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatah if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) + ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15196,7 +15196,7 @@ func (ec *executionContext) marshalOID2ᚖstring(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { +func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { if v == nil { return nil, nil } @@ -15204,7 +15204,7 @@ func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatah return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { +func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15231,7 +15231,7 @@ func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahub if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) + ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15305,7 +15305,7 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as return res } -func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { +func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15332,7 +15332,7 @@ func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmo if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐType(ctx, sel, v[i]) + ret[i] = ec.marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15352,7 +15352,7 @@ func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmo return ret } -func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { +func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { if v == nil { return nil, nil } @@ -15360,7 +15360,7 @@ func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahub return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { +func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15387,7 +15387,7 @@ func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahu if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) } if isLen1 { f(i) diff --git a/server/graph/resolver.go b/pkg/server/graph/resolver.go similarity index 100% rename from server/graph/resolver.go rename to pkg/server/graph/resolver.go diff --git a/server/graph/schema.resolvers.go b/pkg/server/graph/schema.resolvers.go similarity index 97% rename from server/graph/schema.resolvers.go rename to pkg/server/graph/schema.resolvers.go index 2e5d20fb..f32c7cfc 100644 --- a/server/graph/schema.resolvers.go +++ b/pkg/server/graph/schema.resolvers.go @@ -8,7 +8,7 @@ import ( "context" "fmt" - "github.com/opendatahub-io/model-registry/model/graph" + "github.com/opendatahub-io/model-registry/pkg/model/graph" ) // Types is the resolver for the types field. diff --git a/server/grpc_server.go b/pkg/server/grpc_server.go similarity index 68% rename from server/grpc_server.go rename to pkg/server/grpc_server.go index 80441f42..bb943e72 100644 --- a/server/grpc_server.go +++ b/pkg/server/grpc_server.go @@ -3,8 +3,8 @@ package server import ( "context" "fmt" - "github.com/opendatahub-io/model-registry/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/model/db" + proto2 "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" + db2 "github.com/opendatahub-io/model-registry/pkg/model/db" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" @@ -32,20 +32,20 @@ func (tk TypeKind) String() string { } type grpcServer struct { - proto.UnimplementedMetadataStoreServiceServer + proto2.UnimplementedMetadataStoreServiceServer dbConnection *gorm.DB } -var _ proto.MetadataStoreServiceServer = grpcServer{} -var _ proto.MetadataStoreServiceServer = (*grpcServer)(nil) +var _ proto2.MetadataStoreServiceServer = grpcServer{} +var _ proto2.MetadataStoreServiceServer = (*grpcServer)(nil) -func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { +func NewGrpcServer(dbConnection *gorm.DB) proto2.MetadataStoreServiceServer { return &grpcServer{dbConnection: dbConnection} } var REQUIRED_TYPE_FIELDS = []string{"name"} -func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { +func (g grpcServer) PutArtifactType(ctx context.Context, request *proto2.PutArtifactTypeRequest) (resp *proto2.PutArtifactTypeResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -55,7 +55,7 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif if err != nil { return nil, err } - value := &db.Type{ + value := &db2.Type{ Name: *artifactType.Name, Version: artifactType.Version, TypeKind: int32(ARTIFACT_TYPE), @@ -67,13 +67,13 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif return nil, err } var typeId = int64(value.ID) - return &proto.PutArtifactTypeResponse{ + return &proto2.PutArtifactTypeResponse{ TypeId: &typeId, }, nil } -func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, - properties map[string]proto.PropertyType) error { +func (g grpcServer) createOrUpdateType(ctx context.Context, value *db2.Type, + properties map[string]proto2.PropertyType) error { // TODO handle CanAdd, CanOmit properties from type request dbConn, _ := FromContext(ctx) @@ -88,7 +88,7 @@ func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, return nil } -func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { +func (g grpcServer) PutExecutionType(ctx context.Context, request *proto2.PutExecutionTypeRequest) (resp *proto2.PutExecutionTypeResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -97,7 +97,7 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec if err != nil { return nil, err } - value := &db.Type{ + value := &db2.Type{ Name: *executionType.Name, Version: executionType.Version, TypeKind: int32(EXECUTION_TYPE), @@ -109,12 +109,12 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec return nil, err } var typeId = int64(value.ID) - return &proto.PutExecutionTypeResponse{ + return &proto2.PutExecutionTypeResponse{ TypeId: &typeId, }, nil } -func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { +func (g grpcServer) PutContextType(ctx context.Context, request *proto2.PutContextTypeRequest) (resp *proto2.PutContextTypeResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -123,7 +123,7 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex if err != nil { return nil, err } - value := &db.Type{ + value := &db2.Type{ Name: *contextType.Name, Version: contextType.Version, TypeKind: int32(CONTEXT_TYPE), @@ -138,20 +138,20 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex return nil, err } var typeId = int64(value.ID) - return &proto.PutContextTypeResponse{ + return &proto2.PutContextTypeResponse{ TypeId: &typeId, }, nil } -func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest) (resp *proto.PutTypesResponse, err error) { +func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesRequest) (resp *proto2.PutTypesResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) - response := &proto.PutTypesResponse{} + response := &proto2.PutTypesResponse{} for _, ar := range request.ArtifactTypes { - var at *proto.PutArtifactTypeResponse - at, err = g.PutArtifactType(ctx, &proto.PutArtifactTypeRequest{ + var at *proto2.PutArtifactTypeResponse + at, err = g.PutArtifactType(ctx, &proto2.PutArtifactTypeRequest{ ArtifactType: ar, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, @@ -165,8 +165,8 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest response.ArtifactTypeIds = append(response.ArtifactTypeIds, *at.TypeId) } for _, ex := range request.ExecutionTypes { - var er *proto.PutExecutionTypeResponse - er, err = g.PutExecutionType(ctx, &proto.PutExecutionTypeRequest{ + var er *proto2.PutExecutionTypeResponse + er, err = g.PutExecutionType(ctx, &proto2.PutExecutionTypeRequest{ ExecutionType: ex, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, @@ -180,8 +180,8 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest response.ExecutionTypeIds = append(response.ExecutionTypeIds, *er.TypeId) } for _, ct := range request.ContextTypes { - var cr *proto.PutContextTypeResponse - cr, err = g.PutContextType(ctx, &proto.PutContextTypeRequest{ + var cr *proto2.PutContextTypeResponse + cr, err = g.PutContextType(ctx, &proto2.PutContextTypeRequest{ ContextType: ct, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, @@ -199,7 +199,7 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest var REQUIRED_ARTIFACT_FIELDS = []string{"type_id", "uri"} -func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (resp *proto.PutArtifactsResponse, err error) { +func (g grpcServer) PutArtifacts(ctx context.Context, request *proto2.PutArtifactsRequest) (resp *proto2.PutArtifactsResponse, err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -209,7 +209,7 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifact if err != nil { return nil, err } - value := &db.Artifact{ + value := &db2.Artifact{ TypeID: *artifact.TypeId, URI: artifact.Uri, Name: artifact.Name, @@ -233,243 +233,243 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifact } artifactIds = append(artifactIds, int64(value.ID)) } - resp = &proto.PutArtifactsResponse{ + resp = &proto2.PutArtifactsResponse{ ArtifactIds: artifactIds, } return resp, nil } -func (g grpcServer) PutExecutions(ctx context.Context, request *proto.PutExecutionsRequest) (*proto.PutExecutionsResponse, error) { +func (g grpcServer) PutExecutions(ctx context.Context, request *proto2.PutExecutionsRequest) (*proto2.PutExecutionsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutEvents(ctx context.Context, request *proto.PutEventsRequest) (*proto.PutEventsResponse, error) { +func (g grpcServer) PutEvents(ctx context.Context, request *proto2.PutEventsRequest) (*proto2.PutEventsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutExecution(ctx context.Context, request *proto.PutExecutionRequest) (*proto.PutExecutionResponse, error) { +func (g grpcServer) PutExecution(ctx context.Context, request *proto2.PutExecutionRequest) (*proto2.PutExecutionResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutLineageSubgraph(ctx context.Context, request *proto.PutLineageSubgraphRequest) (*proto.PutLineageSubgraphResponse, error) { +func (g grpcServer) PutLineageSubgraph(ctx context.Context, request *proto2.PutLineageSubgraphRequest) (*proto2.PutLineageSubgraphResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutContexts(ctx context.Context, request *proto.PutContextsRequest) (*proto.PutContextsResponse, error) { +func (g grpcServer) PutContexts(ctx context.Context, request *proto2.PutContextsRequest) (*proto2.PutContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutAttributionsAndAssociations(ctx context.Context, request *proto.PutAttributionsAndAssociationsRequest) (*proto.PutAttributionsAndAssociationsResponse, error) { +func (g grpcServer) PutAttributionsAndAssociations(ctx context.Context, request *proto2.PutAttributionsAndAssociationsRequest) (*proto2.PutAttributionsAndAssociationsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutParentContexts(ctx context.Context, request *proto.PutParentContextsRequest) (*proto.PutParentContextsResponse, error) { +func (g grpcServer) PutParentContexts(ctx context.Context, request *proto2.PutParentContextsRequest) (*proto2.PutParentContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (*proto.GetArtifactTypeResponse, error) { +func (g grpcServer) GetArtifactType(ctx context.Context, request *proto2.GetArtifactTypeRequest) (*proto2.GetArtifactTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactTypesByID(ctx context.Context, request *proto.GetArtifactTypesByIDRequest) (*proto.GetArtifactTypesByIDResponse, error) { +func (g grpcServer) GetArtifactTypesByID(ctx context.Context, request *proto2.GetArtifactTypesByIDRequest) (*proto2.GetArtifactTypesByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactTypes(ctx context.Context, request *proto.GetArtifactTypesRequest) (*proto.GetArtifactTypesResponse, error) { +func (g grpcServer) GetArtifactTypes(ctx context.Context, request *proto2.GetArtifactTypesRequest) (*proto2.GetArtifactTypesResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionType(ctx context.Context, request *proto.GetExecutionTypeRequest) (*proto.GetExecutionTypeResponse, error) { +func (g grpcServer) GetExecutionType(ctx context.Context, request *proto2.GetExecutionTypeRequest) (*proto2.GetExecutionTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionTypesByID(ctx context.Context, request *proto.GetExecutionTypesByIDRequest) (*proto.GetExecutionTypesByIDResponse, error) { +func (g grpcServer) GetExecutionTypesByID(ctx context.Context, request *proto2.GetExecutionTypesByIDRequest) (*proto2.GetExecutionTypesByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionTypes(ctx context.Context, request *proto.GetExecutionTypesRequest) (*proto.GetExecutionTypesResponse, error) { +func (g grpcServer) GetExecutionTypes(ctx context.Context, request *proto2.GetExecutionTypesRequest) (*proto2.GetExecutionTypesResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextType(ctx context.Context, request *proto.GetContextTypeRequest) (*proto.GetContextTypeResponse, error) { +func (g grpcServer) GetContextType(ctx context.Context, request *proto2.GetContextTypeRequest) (*proto2.GetContextTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextTypesByID(ctx context.Context, request *proto.GetContextTypesByIDRequest) (*proto.GetContextTypesByIDResponse, error) { +func (g grpcServer) GetContextTypesByID(ctx context.Context, request *proto2.GetContextTypesByIDRequest) (*proto2.GetContextTypesByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextTypes(ctx context.Context, request *proto.GetContextTypesRequest) (*proto.GetContextTypesResponse, error) { +func (g grpcServer) GetContextTypes(ctx context.Context, request *proto2.GetContextTypesRequest) (*proto2.GetContextTypesResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifacts(ctx context.Context, request *proto.GetArtifactsRequest) (*proto.GetArtifactsResponse, error) { +func (g grpcServer) GetArtifacts(ctx context.Context, request *proto2.GetArtifactsRequest) (*proto2.GetArtifactsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutions(ctx context.Context, request *proto.GetExecutionsRequest) (*proto.GetExecutionsResponse, error) { +func (g grpcServer) GetExecutions(ctx context.Context, request *proto2.GetExecutionsRequest) (*proto2.GetExecutionsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContexts(ctx context.Context, request *proto.GetContextsRequest) (*proto.GetContextsResponse, error) { +func (g grpcServer) GetContexts(ctx context.Context, request *proto2.GetContextsRequest) (*proto2.GetContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByID(ctx context.Context, request *proto.GetArtifactsByIDRequest) (*proto.GetArtifactsByIDResponse, error) { +func (g grpcServer) GetArtifactsByID(ctx context.Context, request *proto2.GetArtifactsByIDRequest) (*proto2.GetArtifactsByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByID(ctx context.Context, request *proto.GetExecutionsByIDRequest) (*proto.GetExecutionsByIDResponse, error) { +func (g grpcServer) GetExecutionsByID(ctx context.Context, request *proto2.GetExecutionsByIDRequest) (*proto2.GetExecutionsByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByID(ctx context.Context, request *proto.GetContextsByIDRequest) (*proto.GetContextsByIDResponse, error) { +func (g grpcServer) GetContextsByID(ctx context.Context, request *proto2.GetContextsByIDRequest) (*proto2.GetContextsByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByType(ctx context.Context, request *proto.GetArtifactsByTypeRequest) (*proto.GetArtifactsByTypeResponse, error) { +func (g grpcServer) GetArtifactsByType(ctx context.Context, request *proto2.GetArtifactsByTypeRequest) (*proto2.GetArtifactsByTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByType(ctx context.Context, request *proto.GetExecutionsByTypeRequest) (*proto.GetExecutionsByTypeResponse, error) { +func (g grpcServer) GetExecutionsByType(ctx context.Context, request *proto2.GetExecutionsByTypeRequest) (*proto2.GetExecutionsByTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByType(ctx context.Context, request *proto.GetContextsByTypeRequest) (*proto.GetContextsByTypeResponse, error) { +func (g grpcServer) GetContextsByType(ctx context.Context, request *proto2.GetContextsByTypeRequest) (*proto2.GetContextsByTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactByTypeAndName(ctx context.Context, request *proto.GetArtifactByTypeAndNameRequest) (*proto.GetArtifactByTypeAndNameResponse, error) { +func (g grpcServer) GetArtifactByTypeAndName(ctx context.Context, request *proto2.GetArtifactByTypeAndNameRequest) (*proto2.GetArtifactByTypeAndNameResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionByTypeAndName(ctx context.Context, request *proto.GetExecutionByTypeAndNameRequest) (*proto.GetExecutionByTypeAndNameResponse, error) { +func (g grpcServer) GetExecutionByTypeAndName(ctx context.Context, request *proto2.GetExecutionByTypeAndNameRequest) (*proto2.GetExecutionByTypeAndNameResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextByTypeAndName(ctx context.Context, request *proto.GetContextByTypeAndNameRequest) (*proto.GetContextByTypeAndNameResponse, error) { +func (g grpcServer) GetContextByTypeAndName(ctx context.Context, request *proto2.GetContextByTypeAndNameRequest) (*proto2.GetContextByTypeAndNameResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByURI(ctx context.Context, request *proto.GetArtifactsByURIRequest) (*proto.GetArtifactsByURIResponse, error) { +func (g grpcServer) GetArtifactsByURI(ctx context.Context, request *proto2.GetArtifactsByURIRequest) (*proto2.GetArtifactsByURIResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetEventsByExecutionIDs(ctx context.Context, request *proto.GetEventsByExecutionIDsRequest) (*proto.GetEventsByExecutionIDsResponse, error) { +func (g grpcServer) GetEventsByExecutionIDs(ctx context.Context, request *proto2.GetEventsByExecutionIDsRequest) (*proto2.GetEventsByExecutionIDsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetEventsByArtifactIDs(ctx context.Context, request *proto.GetEventsByArtifactIDsRequest) (*proto.GetEventsByArtifactIDsResponse, error) { +func (g grpcServer) GetEventsByArtifactIDs(ctx context.Context, request *proto2.GetEventsByArtifactIDsRequest) (*proto2.GetEventsByArtifactIDsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByExternalIds(ctx context.Context, request *proto.GetArtifactsByExternalIdsRequest) (*proto.GetArtifactsByExternalIdsResponse, error) { +func (g grpcServer) GetArtifactsByExternalIds(ctx context.Context, request *proto2.GetArtifactsByExternalIdsRequest) (*proto2.GetArtifactsByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByExternalIds(ctx context.Context, request *proto.GetExecutionsByExternalIdsRequest) (*proto.GetExecutionsByExternalIdsResponse, error) { +func (g grpcServer) GetExecutionsByExternalIds(ctx context.Context, request *proto2.GetExecutionsByExternalIdsRequest) (*proto2.GetExecutionsByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByExternalIds(ctx context.Context, request *proto.GetContextsByExternalIdsRequest) (*proto.GetContextsByExternalIdsResponse, error) { +func (g grpcServer) GetContextsByExternalIds(ctx context.Context, request *proto2.GetContextsByExternalIdsRequest) (*proto2.GetContextsByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactTypesByExternalIds(ctx context.Context, request *proto.GetArtifactTypesByExternalIdsRequest) (*proto.GetArtifactTypesByExternalIdsResponse, error) { +func (g grpcServer) GetArtifactTypesByExternalIds(ctx context.Context, request *proto2.GetArtifactTypesByExternalIdsRequest) (*proto2.GetArtifactTypesByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionTypesByExternalIds(ctx context.Context, request *proto.GetExecutionTypesByExternalIdsRequest) (*proto.GetExecutionTypesByExternalIdsResponse, error) { +func (g grpcServer) GetExecutionTypesByExternalIds(ctx context.Context, request *proto2.GetExecutionTypesByExternalIdsRequest) (*proto2.GetExecutionTypesByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextTypesByExternalIds(ctx context.Context, request *proto.GetContextTypesByExternalIdsRequest) (*proto.GetContextTypesByExternalIdsResponse, error) { +func (g grpcServer) GetContextTypesByExternalIds(ctx context.Context, request *proto2.GetContextTypesByExternalIdsRequest) (*proto2.GetContextTypesByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByArtifact(ctx context.Context, request *proto.GetContextsByArtifactRequest) (*proto.GetContextsByArtifactResponse, error) { +func (g grpcServer) GetContextsByArtifact(ctx context.Context, request *proto2.GetContextsByArtifactRequest) (*proto2.GetContextsByArtifactResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByExecution(ctx context.Context, request *proto.GetContextsByExecutionRequest) (*proto.GetContextsByExecutionResponse, error) { +func (g grpcServer) GetContextsByExecution(ctx context.Context, request *proto2.GetContextsByExecutionRequest) (*proto2.GetContextsByExecutionResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetParentContextsByContext(ctx context.Context, request *proto.GetParentContextsByContextRequest) (*proto.GetParentContextsByContextResponse, error) { +func (g grpcServer) GetParentContextsByContext(ctx context.Context, request *proto2.GetParentContextsByContextRequest) (*proto2.GetParentContextsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetChildrenContextsByContext(ctx context.Context, request *proto.GetChildrenContextsByContextRequest) (*proto.GetChildrenContextsByContextResponse, error) { +func (g grpcServer) GetChildrenContextsByContext(ctx context.Context, request *proto2.GetChildrenContextsByContextRequest) (*proto2.GetChildrenContextsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetParentContextsByContexts(ctx context.Context, request *proto.GetParentContextsByContextsRequest) (*proto.GetParentContextsByContextsResponse, error) { +func (g grpcServer) GetParentContextsByContexts(ctx context.Context, request *proto2.GetParentContextsByContextsRequest) (*proto2.GetParentContextsByContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetChildrenContextsByContexts(ctx context.Context, request *proto.GetChildrenContextsByContextsRequest) (*proto.GetChildrenContextsByContextsResponse, error) { +func (g grpcServer) GetChildrenContextsByContexts(ctx context.Context, request *proto2.GetChildrenContextsByContextsRequest) (*proto2.GetChildrenContextsByContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByContext(ctx context.Context, request *proto.GetArtifactsByContextRequest) (*proto.GetArtifactsByContextResponse, error) { +func (g grpcServer) GetArtifactsByContext(ctx context.Context, request *proto2.GetArtifactsByContextRequest) (*proto2.GetArtifactsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByContext(ctx context.Context, request *proto.GetExecutionsByContextRequest) (*proto.GetExecutionsByContextResponse, error) { +func (g grpcServer) GetExecutionsByContext(ctx context.Context, request *proto2.GetExecutionsByContextRequest) (*proto2.GetExecutionsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetLineageGraph(ctx context.Context, request *proto.GetLineageGraphRequest) (*proto.GetLineageGraphResponse, error) { +func (g grpcServer) GetLineageGraph(ctx context.Context, request *proto2.GetLineageGraphRequest) (*proto2.GetLineageGraphResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetLineageSubgraph(ctx context.Context, request *proto.GetLineageSubgraphRequest) (*proto.GetLineageSubgraphResponse, error) { +func (g grpcServer) GetLineageSubgraph(ctx context.Context, request *proto2.GetLineageSubgraphRequest) (*proto2.GetLineageSubgraphResponse, error) { //TODO implement me panic("implement me") } @@ -479,13 +479,13 @@ func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { panic("implement me") } -func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, typeId int64) (err error) { +func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto2.PropertyType, typeId int64) (err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { number := int32(prop.Number()) - property := &db.TypeProperty{ + property := &db2.TypeProperty{ TypeID: typeId, Name: propName, DataType: number, @@ -499,12 +499,12 @@ func (g grpcServer) createTypeProperties(ctx context.Context, properties map[str return nil } -func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto.Value, isCustomProperty bool) (err error) { +func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto2.Value, isCustomProperty bool) (err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { - property := &db.ArtifactProperty{ + property := &db2.ArtifactProperty{ ArtifactID: artifactId, Name: propName, } @@ -512,19 +512,19 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int property.IsCustomProperty = true } // TODO handle polymorphic value with null columns - intValue, ok := prop.GetValue().(*proto.Value_IntValue) + intValue, ok := prop.GetValue().(*proto2.Value_IntValue) if ok { property.IntValue = &intValue.IntValue } - doubleValue, ok := prop.GetValue().(*proto.Value_DoubleValue) + doubleValue, ok := prop.GetValue().(*proto2.Value_DoubleValue) if ok { property.DoubleValue = &doubleValue.DoubleValue } - stringValue, ok := prop.GetValue().(*proto.Value_StringValue) + stringValue, ok := prop.GetValue().(*proto2.Value_StringValue) if ok { property.StringValue = &stringValue.StringValue } - structValue, ok := prop.GetValue().(*proto.Value_StructValue) + structValue, ok := prop.GetValue().(*proto2.Value_StructValue) if ok { json, err2 := structValue.StructValue.MarshalJSON() if err2 != nil { @@ -533,11 +533,11 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int } property.ByteValue = &json } - protoValue, ok := prop.GetValue().(*proto.Value_ProtoValue) + protoValue, ok := prop.GetValue().(*proto2.Value_ProtoValue) if ok { property.ProtoValue = &protoValue.ProtoValue.Value } - boolValue, ok := prop.GetValue().(*proto.Value_BoolValue) + boolValue, ok := prop.GetValue().(*proto2.Value_BoolValue) if ok { property.BoolValue = &boolValue.BoolValue } @@ -550,7 +550,7 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int } func identity[T int64 | string](i T) T { return i } -func artifactStateToInt64(i proto.Artifact_State) *int64 { +func artifactStateToInt64(i proto2.Artifact_State) *int64 { var result = int64(i) return &result } @@ -568,7 +568,7 @@ func requiredFields(names []string, args ...interface{}) error { return nil } -func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { +func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto2.Artifact_State | string](dest *D, src *S, f func(i S) D) { if src != nil { *dest = f(*src) } From 0f8e1635b3be92874ac69d791573fd33733ee130 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Sun, 17 Sep 2023 16:44:31 -0700 Subject: [PATCH 031/254] Added lint to Makefile --- Makefile | 6 +++++- pkg/server/grpc_server.go | 10 ++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 6afb84d0..429ad72b 100644 --- a/Makefile +++ b/Makefile @@ -26,12 +26,16 @@ vendor: go mod vendor .PHONY: build -build: gen vet +build: gen vet lint go build .PHONY: gen gen: gen/grpc gen/graph +.PHONY: lint +lint: gen + golangci-lint run cmd/... pkg/... + .PHONY: run/migrate run/migrate: gen go run main.go migrate --logtostderr=true diff --git a/pkg/server/grpc_server.go b/pkg/server/grpc_server.go index bb943e72..b0deb1df 100644 --- a/pkg/server/grpc_server.go +++ b/pkg/server/grpc_server.go @@ -155,8 +155,6 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesReques ArtifactType: ar, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, - CanDeleteFields: request.CanDeleteFields, - AllFieldsMatch: request.AllFieldsMatch, TransactionOptions: request.TransactionOptions, }) if err != nil { @@ -170,8 +168,6 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesReques ExecutionType: ex, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, - CanDeleteFields: request.CanDeleteFields, - AllFieldsMatch: request.AllFieldsMatch, TransactionOptions: request.TransactionOptions, }) if err != nil { @@ -185,8 +181,6 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesReques ContextType: ct, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, - CanDeleteFields: request.CanDeleteFields, - AllFieldsMatch: request.AllFieldsMatch, TransactionOptions: request.TransactionOptions, }) if err != nil { @@ -474,9 +468,9 @@ func (g grpcServer) GetLineageSubgraph(ctx context.Context, request *proto2.GetL panic("implement me") } +//nolint:golint,unused func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { - //TODO implement me - panic("implement me") + // implemented to signal that server is extendable } func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto2.PropertyType, typeId int64) (err error) { From 4aae325e5ea28f1c0a87004aa054ebde42df4724 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Mon, 18 Sep 2023 20:12:05 -0700 Subject: [PATCH 032/254] Added go tools install commands to README --- Makefile | 1 + README.md | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 429ad72b..5c4e62aa 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ gen: gen/grpc gen/graph .PHONY: lint lint: gen + golangci-lint run main.go golangci-lint run cmd/... pkg/... .PHONY: run/migrate diff --git a/README.md b/README.md index 9e8fa804..5a900a2f 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,11 @@ It adds other features on top of the functionality offered by the gRPC interface ## Pre-requisites: - go >= 1.19 - protoc - [Protocol buffer compiler](https://grpc.io/docs/protoc-installation/). +- go tools - Installed with the following commands: +``` +go install github.com/99designs/gqlgen@latest +go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest +``` - gRPC go plugins - Installed with the following commands: ``` go install google.golang.org/protobuf/cmd/protoc-gen-go@latest From 88ca5d59002b4a936de6cb90e5c5e5fec79821c3 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Wed, 20 Sep 2023 09:39:08 +0200 Subject: [PATCH 033/254] Fix golangci-lint local install instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a900a2f..83b3ca3b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ It adds other features on top of the functionality offered by the gRPC interface - go tools - Installed with the following commands: ``` go install github.com/99designs/gqlgen@latest -go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest +curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2 ``` - gRPC go plugins - Installed with the following commands: ``` From 11f65a9bbd849962979c71e1e86fdfc8ff7b88f9 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 19 Sep 2023 17:31:01 -0700 Subject: [PATCH 034/254] Added go-enum local install instructions --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 83b3ca3b..1fd8fa37 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ It adds other features on top of the functionality offered by the gRPC interface ``` go install github.com/99designs/gqlgen@latest curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2 +go install github.com/searKing/golang/tools/go-enum@latest ``` - gRPC go plugins - Installed with the following commands: ``` From 7782ec49743465e82f05374441f4b27f46c52506 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 20 Sep 2023 09:08:40 -0700 Subject: [PATCH 035/254] Made pkg code private Moved pkg to internal since it's not meant to be exported as reusable pkg outside this project. --- Makefile | 17 +- .../ml_metadata/proto/metadata_source.proto | 2 +- .../ml_metadata/proto/metadata_store.proto | 2 +- .../proto/metadata_store_service.proto | 2 +- cmd/migrate.go | 44 ++-- cmd/root.go | 3 + cmd/serve.go | 8 +- gqlgen.yml | 6 +- .../ml_metadata/proto/metadata_store.pb.go | 9 +- .../proto/metadata_store_service.pb.go | 6 +- .../proto/metadata_store_service_grpc.pb.go | 0 {pkg => internal}/model/db/artifact.gen.go | 0 .../model/db/artifactproperty.gen.go | 0 {pkg => internal}/model/db/association.gen.go | 0 {pkg => internal}/model/db/attribution.gen.go | 0 {pkg => internal}/model/db/context.gen.go | 0 .../model/db/contextproperty.gen.go | 0 {pkg => internal}/model/db/event.gen.go | 0 {pkg => internal}/model/db/eventpath.gen.go | 0 {pkg => internal}/model/db/execution.gen.go | 0 .../model/db/executionproperty.gen.go | 0 {pkg => internal}/model/db/mlmdenv.gen.go | 0 .../model/db/parentcontext.gen.go | 0 {pkg => internal}/model/db/parenttype.gen.go | 0 {pkg => internal}/model/db/type.gen.go | 0 .../model/db/typeproperty.gen.go | 0 {pkg => internal}/model/graph/models_gen.go | 0 .../model/library/metadata_library.go | 2 +- .../model/library/propertytype_enum.go | 0 {pkg => internal}/server/db_context.go | 0 .../server/graph/base-schema.resolvers.go | 2 +- {pkg => internal}/server/graph/generated.go | 188 +++++++++--------- {pkg => internal}/server/graph/resolver.go | 0 .../server/graph/schema.resolvers.go | 2 +- {pkg => internal}/server/grpc_server.go | 174 ++++++++-------- 35 files changed, 236 insertions(+), 231 deletions(-) rename {pkg => internal}/ml_metadata/proto/metadata_store.pb.go (99%) rename {pkg => internal}/ml_metadata/proto/metadata_store_service.pb.go (99%) rename {pkg => internal}/ml_metadata/proto/metadata_store_service_grpc.pb.go (100%) rename {pkg => internal}/model/db/artifact.gen.go (100%) rename {pkg => internal}/model/db/artifactproperty.gen.go (100%) rename {pkg => internal}/model/db/association.gen.go (100%) rename {pkg => internal}/model/db/attribution.gen.go (100%) rename {pkg => internal}/model/db/context.gen.go (100%) rename {pkg => internal}/model/db/contextproperty.gen.go (100%) rename {pkg => internal}/model/db/event.gen.go (100%) rename {pkg => internal}/model/db/eventpath.gen.go (100%) rename {pkg => internal}/model/db/execution.gen.go (100%) rename {pkg => internal}/model/db/executionproperty.gen.go (100%) rename {pkg => internal}/model/db/mlmdenv.gen.go (100%) rename {pkg => internal}/model/db/parentcontext.gen.go (100%) rename {pkg => internal}/model/db/parenttype.gen.go (100%) rename {pkg => internal}/model/db/type.gen.go (100%) rename {pkg => internal}/model/db/typeproperty.gen.go (100%) rename {pkg => internal}/model/graph/models_gen.go (100%) rename {pkg => internal}/model/library/metadata_library.go (95%) rename {pkg => internal}/model/library/propertytype_enum.go (100%) rename {pkg => internal}/server/db_context.go (100%) rename {pkg => internal}/server/graph/base-schema.resolvers.go (91%) rename {pkg => internal}/server/graph/generated.go (97%) rename {pkg => internal}/server/graph/resolver.go (100%) rename {pkg => internal}/server/graph/schema.resolvers.go (97%) rename {pkg => internal}/server/grpc_server.go (67%) diff --git a/Makefile b/Makefile index 5c4e62aa..1fdd8ba3 100644 --- a/Makefile +++ b/Makefile @@ -1,16 +1,16 @@ model-registry: build -pkg/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto - protoc -I./api/grpc --go_out=./pkg --go_opt=paths=source_relative \ - --go-grpc_out=./pkg --go-grpc_opt=paths=source_relative $< +internal/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto + protoc -I./api/grpc --go_out=./internal --go_opt=paths=source_relative \ + --go-grpc_out=./internal --go-grpc_opt=paths=source_relative $< .PHONY: gen/grpc -gen/grpc: pkg/ml_metadata/proto/metadata_store.pb.go pkg/ml_metadata/proto/metadata_store_service.pb.go +gen/grpc: internal/ml_metadata/proto/metadata_store.pb.go internal/ml_metadata/proto/metadata_store_service.pb.go .PHONY: gen/graph -gen/graph: pkg/model/graph/models_gen.go +gen/graph: internal/model/graph/models_gen.go -pkg/model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml +internal/model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml go run github.com/99designs/gqlgen generate .PHONY: vet @@ -19,7 +19,7 @@ vet: .PHONY: clean clean: - rm -Rf ./model-registry pkg/ml_metadata/proto/*.go pkg/model/graph/*.go + rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/*.go .PHONY: vendor vendor: @@ -31,11 +31,12 @@ build: gen vet lint .PHONY: gen gen: gen/grpc gen/graph + go generate ./... .PHONY: lint lint: gen golangci-lint run main.go - golangci-lint run cmd/... pkg/... + golangci-lint run cmd/... internal/... .PHONY: run/migrate run/migrate: gen diff --git a/api/grpc/ml_metadata/proto/metadata_source.proto b/api/grpc/ml_metadata/proto/metadata_source.proto index 529ecad5..7798a421 100644 --- a/api/grpc/ml_metadata/proto/metadata_source.proto +++ b/api/grpc/ml_metadata/proto/metadata_source.proto @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ // The returned results from a MetadataSource. syntax = "proto3"; -option go_package = "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto"; package ml_metadata; diff --git a/api/grpc/ml_metadata/proto/metadata_store.proto b/api/grpc/ml_metadata/proto/metadata_store.proto index f55ffb20..8e59ff6c 100644 --- a/api/grpc/ml_metadata/proto/metadata_store.proto +++ b/api/grpc/ml_metadata/proto/metadata_store.proto @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. ==============================================================================*/ syntax = "proto2"; -option go_package = "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto"; package ml_metadata; diff --git a/api/grpc/ml_metadata/proto/metadata_store_service.proto b/api/grpc/ml_metadata/proto/metadata_store_service.proto index 485d683c..f4a16919 100644 --- a/api/grpc/ml_metadata/proto/metadata_store_service.proto +++ b/api/grpc/ml_metadata/proto/metadata_store_service.proto @@ -14,7 +14,7 @@ limitations under the License. ==============================================================================*/ syntax = "proto2"; -option go_package = "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto"; +option go_package = "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto"; package ml_metadata; diff --git a/cmd/migrate.go b/cmd/migrate.go index 9032b3ab..43d68a18 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -19,12 +19,12 @@ import ( "context" "fmt" "github.com/golang/glog" - proto2 "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" - db2 "github.com/opendatahub-io/model-registry/pkg/model/db" - "github.com/opendatahub-io/model-registry/pkg/model/library" - "github.com/opendatahub-io/model-registry/pkg/server" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/db" + "github.com/opendatahub-io/model-registry/internal/model/library" + "github.com/opendatahub-io/model-registry/internal/server" "github.com/spf13/cobra" - yaml "gopkg.in/yaml.v3" + "gopkg.in/yaml.v3" "gorm.io/gorm" "io/fs" "os" @@ -75,19 +75,19 @@ to the latest schema required by this server.`, func migrateDatabase(dbConn *gorm.DB) error { // TODO add support for more elaborate Gorm migrations err := dbConn.AutoMigrate( - db2.Artifact{}, - db2.ArtifactProperty{}, - db2.Association{}, - db2.Attribution{}, - db2.Context{}, - db2.ContextProperty{}, - db2.Event{}, - db2.EventPath{}, - db2.Execution{}, - db2.ExecutionProperty{}, - db2.ParentContext{}, - db2.Type{}, - db2.TypeProperty{}, + db.Artifact{}, + db.ArtifactProperty{}, + db.Association{}, + db.Attribution{}, + db.Context{}, + db.ContextProperty{}, + db.Event{}, + db.EventPath{}, + db.Execution{}, + db.ExecutionProperty{}, + db.ParentContext{}, + db.Type{}, + db.TypeProperty{}, ) if err != nil { return fmt.Errorf("db migration failed: %w", err) @@ -124,9 +124,9 @@ func loadLibraries(dbConn *gorm.DB) error { return fmt.Errorf("failed to parse library file %s: %w", path, err) } grpcServer := server.NewGrpcServer(dbConn) - typesRequest := proto2.PutTypesRequest{} + typesRequest := proto.PutTypesRequest{} for _, at := range lib.ArtifactTypes { - typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto2.ArtifactType{ + typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ Name: at.Name, Version: at.Version, Description: at.Description, @@ -135,7 +135,7 @@ func loadLibraries(dbConn *gorm.DB) error { }) } for _, ct := range lib.ContextTypes { - typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto2.ContextType{ + typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ Name: ct.Name, Version: ct.Version, Description: ct.Description, @@ -144,7 +144,7 @@ func loadLibraries(dbConn *gorm.DB) error { }) } for _, et := range lib.ExecutionTypes { - typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto2.ExecutionType{ + typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ Name: et.Name, Version: et.Version, Description: et.Description, diff --git a/cmd/root.go b/cmd/root.go index 38537913..80b714b4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -62,6 +62,9 @@ func init() { // will be global for your application. rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.model-registry.yaml)") + + // default to logging to stderr + _ = flag.Set("logtostderr", "true") // also add standard glog flags rootCmd.PersistentFlags().AddGoFlagSet(flag.CommandLine) diff --git a/cmd/serve.go b/cmd/serve.go index 12eb4230..5878bcb7 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -22,9 +22,9 @@ import ( "github.com/99designs/gqlgen/graphql/playground" "github.com/golang/glog" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/pkg/server" - graph2 "github.com/opendatahub-io/model-registry/pkg/server/graph" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/server" + "github.com/opendatahub-io/model-registry/internal/server/graph" "github.com/soheilhy/cmux" "github.com/spf13/cobra" "golang.org/x/sync/errgroup" @@ -154,7 +154,7 @@ func runServer(cmd *cobra.Command, args []string) error { func graphQlListenerServer(listener net.Listener, db *gorm.DB) *http.Server { mux := http.NewServeMux() - srv := handler.NewDefaultServer(graph2.NewExecutableSchema(graph2.Config{Resolvers: &graph2.Resolver{}})) + srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})) mux.Handle("/", playground.Handler("GraphQL playground", "/query")) mux.Handle("/query", srv) diff --git a/gqlgen.yml b/gqlgen.yml index d281fe81..34decc08 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -4,7 +4,7 @@ schema: # Where should the generated server code go? exec: - filename: pkg/server/graph/generated.go + filename: internal/server/graph/generated.go package: graph # Uncomment to enable federation @@ -14,13 +14,13 @@ exec: # Where should any generated models go? model: - filename: pkg/model/graph/models_gen.go + filename: internal/model/graph/models_gen.go package: graph # Where should the resolver implementations go? resolver: layout: follow-schema - dir: pkg/server/graph + dir: internal/server/graph package: graph filename_template: "{name}.resolvers.go" # Optional: turn on to not generate template comments above resolvers diff --git a/pkg/ml_metadata/proto/metadata_store.pb.go b/internal/ml_metadata/proto/metadata_store.pb.go similarity index 99% rename from pkg/ml_metadata/proto/metadata_store.pb.go rename to internal/ml_metadata/proto/metadata_store.pb.go index eab133b4..0d89cd2a 100644 --- a/pkg/ml_metadata/proto/metadata_store.pb.go +++ b/internal/ml_metadata/proto/metadata_store.pb.go @@ -5662,11 +5662,12 @@ var file_ml_metadata_proto_metadata_store_proto_rawDesc = []byte{ 0xb7, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x54, 0x79, 0x70, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x54, 0x79, 0x70, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x40, 0x5a, - 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x45, 0x5a, + 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x68, 0x75, 0x62, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, - 0x2d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x6c, - 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x2f, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, } var ( diff --git a/pkg/ml_metadata/proto/metadata_store_service.pb.go b/internal/ml_metadata/proto/metadata_store_service.pb.go similarity index 99% rename from pkg/ml_metadata/proto/metadata_store_service.pb.go rename to internal/ml_metadata/proto/metadata_store_service.pb.go index 23d7248b..fadd1ce2 100644 --- a/pkg/ml_metadata/proto/metadata_store_service.pb.go +++ b/internal/ml_metadata/proto/metadata_store_service.pb.go @@ -8399,11 +8399,11 @@ var file_ml_metadata_proto_metadata_store_service_proto_rawDesc = []byte{ 0x70, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x67, 0x72, 0x61, 0x70, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x73, 0x65, 0x22, 0x00, 0x42, 0x45, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x68, 0x75, 0x62, 0x2d, 0x69, 0x6f, 0x2f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x2d, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x6d, 0x6c, 0x5f, 0x6d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, } var ( diff --git a/pkg/ml_metadata/proto/metadata_store_service_grpc.pb.go b/internal/ml_metadata/proto/metadata_store_service_grpc.pb.go similarity index 100% rename from pkg/ml_metadata/proto/metadata_store_service_grpc.pb.go rename to internal/ml_metadata/proto/metadata_store_service_grpc.pb.go diff --git a/pkg/model/db/artifact.gen.go b/internal/model/db/artifact.gen.go similarity index 100% rename from pkg/model/db/artifact.gen.go rename to internal/model/db/artifact.gen.go diff --git a/pkg/model/db/artifactproperty.gen.go b/internal/model/db/artifactproperty.gen.go similarity index 100% rename from pkg/model/db/artifactproperty.gen.go rename to internal/model/db/artifactproperty.gen.go diff --git a/pkg/model/db/association.gen.go b/internal/model/db/association.gen.go similarity index 100% rename from pkg/model/db/association.gen.go rename to internal/model/db/association.gen.go diff --git a/pkg/model/db/attribution.gen.go b/internal/model/db/attribution.gen.go similarity index 100% rename from pkg/model/db/attribution.gen.go rename to internal/model/db/attribution.gen.go diff --git a/pkg/model/db/context.gen.go b/internal/model/db/context.gen.go similarity index 100% rename from pkg/model/db/context.gen.go rename to internal/model/db/context.gen.go diff --git a/pkg/model/db/contextproperty.gen.go b/internal/model/db/contextproperty.gen.go similarity index 100% rename from pkg/model/db/contextproperty.gen.go rename to internal/model/db/contextproperty.gen.go diff --git a/pkg/model/db/event.gen.go b/internal/model/db/event.gen.go similarity index 100% rename from pkg/model/db/event.gen.go rename to internal/model/db/event.gen.go diff --git a/pkg/model/db/eventpath.gen.go b/internal/model/db/eventpath.gen.go similarity index 100% rename from pkg/model/db/eventpath.gen.go rename to internal/model/db/eventpath.gen.go diff --git a/pkg/model/db/execution.gen.go b/internal/model/db/execution.gen.go similarity index 100% rename from pkg/model/db/execution.gen.go rename to internal/model/db/execution.gen.go diff --git a/pkg/model/db/executionproperty.gen.go b/internal/model/db/executionproperty.gen.go similarity index 100% rename from pkg/model/db/executionproperty.gen.go rename to internal/model/db/executionproperty.gen.go diff --git a/pkg/model/db/mlmdenv.gen.go b/internal/model/db/mlmdenv.gen.go similarity index 100% rename from pkg/model/db/mlmdenv.gen.go rename to internal/model/db/mlmdenv.gen.go diff --git a/pkg/model/db/parentcontext.gen.go b/internal/model/db/parentcontext.gen.go similarity index 100% rename from pkg/model/db/parentcontext.gen.go rename to internal/model/db/parentcontext.gen.go diff --git a/pkg/model/db/parenttype.gen.go b/internal/model/db/parenttype.gen.go similarity index 100% rename from pkg/model/db/parenttype.gen.go rename to internal/model/db/parenttype.gen.go diff --git a/pkg/model/db/type.gen.go b/internal/model/db/type.gen.go similarity index 100% rename from pkg/model/db/type.gen.go rename to internal/model/db/type.gen.go diff --git a/pkg/model/db/typeproperty.gen.go b/internal/model/db/typeproperty.gen.go similarity index 100% rename from pkg/model/db/typeproperty.gen.go rename to internal/model/db/typeproperty.gen.go diff --git a/pkg/model/graph/models_gen.go b/internal/model/graph/models_gen.go similarity index 100% rename from pkg/model/graph/models_gen.go rename to internal/model/graph/models_gen.go diff --git a/pkg/model/library/metadata_library.go b/internal/model/library/metadata_library.go similarity index 95% rename from pkg/model/library/metadata_library.go rename to internal/model/library/metadata_library.go index b5efaac6..7fb1c06c 100644 --- a/pkg/model/library/metadata_library.go +++ b/internal/model/library/metadata_library.go @@ -1,7 +1,7 @@ package library import ( - "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" ) //go:generate go-enum -type=PropertyType diff --git a/pkg/model/library/propertytype_enum.go b/internal/model/library/propertytype_enum.go similarity index 100% rename from pkg/model/library/propertytype_enum.go rename to internal/model/library/propertytype_enum.go diff --git a/pkg/server/db_context.go b/internal/server/db_context.go similarity index 100% rename from pkg/server/db_context.go rename to internal/server/db_context.go diff --git a/pkg/server/graph/base-schema.resolvers.go b/internal/server/graph/base-schema.resolvers.go similarity index 91% rename from pkg/server/graph/base-schema.resolvers.go rename to internal/server/graph/base-schema.resolvers.go index 94e63bfd..f4f61aa6 100644 --- a/pkg/server/graph/base-schema.resolvers.go +++ b/internal/server/graph/base-schema.resolvers.go @@ -7,7 +7,7 @@ package graph import ( "context" - "github.com/opendatahub-io/model-registry/pkg/model/graph" + "github.com/opendatahub-io/model-registry/internal/model/graph" ) // Type is the resolver for the type field. diff --git a/pkg/server/graph/generated.go b/internal/server/graph/generated.go similarity index 97% rename from pkg/server/graph/generated.go rename to internal/server/graph/generated.go index 2cada429..aae96e2b 100644 --- a/pkg/server/graph/generated.go +++ b/internal/server/graph/generated.go @@ -13,7 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/99designs/gqlgen/graphql/introspection" - "github.com/opendatahub-io/model-registry/pkg/model/graph" + "github.com/opendatahub-io/model-registry/internal/model/graph" gqlparser "github.com/vektah/gqlparser/v2" "github.com/vektah/gqlparser/v2/ast" ) @@ -1933,7 +1933,7 @@ func (ec *executionContext) field_Artifact_type_args(ctx context.Context, rawArg var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -1963,7 +1963,7 @@ func (ec *executionContext) field_Query_artifactTypes_args(ctx context.Context, var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -1978,7 +1978,7 @@ func (ec *executionContext) field_Query_artifacts_args(ctx context.Context, rawA var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -1993,7 +1993,7 @@ func (ec *executionContext) field_Query_contextTypes_args(ctx context.Context, r var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2008,7 +2008,7 @@ func (ec *executionContext) field_Query_contexts_args(ctx context.Context, rawAr var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2023,7 +2023,7 @@ func (ec *executionContext) field_Query_executionTypes_args(ctx context.Context, var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2038,7 +2038,7 @@ func (ec *executionContext) field_Query_executions_args(ctx context.Context, raw var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2053,7 +2053,7 @@ func (ec *executionContext) field_Query_mlmdDataset_args(ctx context.Context, ra var arg0 *graph.InstanceFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) + arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) if err != nil { return nil, err } @@ -2068,7 +2068,7 @@ func (ec *executionContext) field_Query_types_args(ctx context.Context, rawArgs var arg0 *graph.TypeFilter if tmp, ok := rawArgs["filter"]; ok { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) + arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) if err != nil { return nil, err } @@ -2489,7 +2489,7 @@ func (ec *executionContext) _Artifact_type(ctx context.Context, field graphql.Co } res := resTmp.(*graph.ArtifactType) fc.Result = res - return ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) + return ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Artifact_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2557,7 +2557,7 @@ func (ec *executionContext) _Artifact_properties(ctx context.Context, field grap } res := resTmp.([]*graph.ArtifactProperty) fc.Result = res - return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Artifact_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -2737,7 +2737,7 @@ func (ec *executionContext) _ArtifactProperty_propertyValue(ctx context.Context, } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3036,7 +3036,7 @@ func (ec *executionContext) _ArtifactType_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ArtifactType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3390,7 +3390,7 @@ func (ec *executionContext) _Context_type(ctx context.Context, field graphql.Col } res := resTmp.(*graph.ContextType) fc.Result = res - return ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) + return ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3447,7 +3447,7 @@ func (ec *executionContext) _Context_parent(ctx context.Context, field graphql.C } res := resTmp.(*graph.Context) fc.Result = res - return ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3514,7 +3514,7 @@ func (ec *executionContext) _Context_children(ctx context.Context, field graphql } res := resTmp.([]*graph.Context) fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_children(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3581,7 +3581,7 @@ func (ec *executionContext) _Context_attributions(ctx context.Context, field gra } res := resTmp.([]*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_attributions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3644,7 +3644,7 @@ func (ec *executionContext) _Context_associations(ctx context.Context, field gra } res := resTmp.([]*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_associations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3705,7 +3705,7 @@ func (ec *executionContext) _Context_properties(ctx context.Context, field graph } res := resTmp.([]*graph.ContextProperty) fc.Result = res - return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Context_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -3888,7 +3888,7 @@ func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4187,7 +4187,7 @@ func (ec *executionContext) _ContextType_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4453,7 +4453,7 @@ func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.C } res := resTmp.(*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Event_artifact(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -4516,7 +4516,7 @@ func (ec *executionContext) _Event_execution(ctx context.Context, field graphql. } res := resTmp.(*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) + return ec.marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Event_execution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5102,7 +5102,7 @@ func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.C } res := resTmp.(*graph.ExecutionType) fc.Result = res - return ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) + return ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Execution_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5163,7 +5163,7 @@ func (ec *executionContext) _Execution_properties(ctx context.Context, field gra } res := resTmp.([]*graph.ExecutionProperty) fc.Result = res - return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) + return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Execution_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5346,7 +5346,7 @@ func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context } res := resTmp.(graph.Value) fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) + return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -5733,7 +5733,7 @@ func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6084,7 +6084,7 @@ func (ec *executionContext) _MlmdDataset_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdDataset_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6479,7 +6479,7 @@ func (ec *executionContext) _MlmdDeploy_properties(ctx context.Context, field gr } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdDeploy_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -6874,7 +6874,7 @@ func (ec *executionContext) _MlmdEvaluate_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdEvaluate_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7181,7 +7181,7 @@ func (ec *executionContext) _MlmdMetrics_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdMetrics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7488,7 +7488,7 @@ func (ec *executionContext) _MlmdModel_properties(ctx context.Context, field gra } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdModel_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -7883,7 +7883,7 @@ func (ec *executionContext) _MlmdProcess_properties(ctx context.Context, field g } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdProcess_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8190,7 +8190,7 @@ func (ec *executionContext) _MlmdStatistics_properties(ctx context.Context, fiel } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdStatistics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8585,7 +8585,7 @@ func (ec *executionContext) _MlmdTrain_properties(ctx context.Context, field gra } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdTrain_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -8980,7 +8980,7 @@ func (ec *executionContext) _MlmdTransform_properties(ctx context.Context, field } res := resTmp.([]*graph.TypeProperty) fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) + return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_MlmdTransform_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9029,7 +9029,7 @@ func (ec *executionContext) _Query_types(ctx context.Context, field graphql.Coll } res := resTmp.([]graph.Type) fc.Result = res - return ec.marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) + return ec.marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9081,7 +9081,7 @@ func (ec *executionContext) _Query_artifactTypes(ctx context.Context, field grap } res := resTmp.([]*graph.ArtifactType) fc.Result = res - return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) + return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_artifactTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9149,7 +9149,7 @@ func (ec *executionContext) _Query_contextTypes(ctx context.Context, field graph } res := resTmp.([]*graph.ContextType) fc.Result = res - return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) + return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_contextTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9217,7 +9217,7 @@ func (ec *executionContext) _Query_executionTypes(ctx context.Context, field gra } res := resTmp.([]*graph.ExecutionType) fc.Result = res - return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) + return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_executionTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9289,7 +9289,7 @@ func (ec *executionContext) _Query_artifacts(ctx context.Context, field graphql. } res := resTmp.([]*graph.Artifact) fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) + return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_artifacts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9363,7 +9363,7 @@ func (ec *executionContext) _Query_contexts(ctx context.Context, field graphql.C } res := resTmp.([]*graph.Context) fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) + return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_contexts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9441,7 +9441,7 @@ func (ec *executionContext) _Query_executions(ctx context.Context, field graphql } res := resTmp.([]*graph.Execution) fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) + return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_executions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9513,7 +9513,7 @@ func (ec *executionContext) _Query_events(ctx context.Context, field graphql.Col } res := resTmp.([]*graph.Event) fc.Result = res - return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) + return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -9570,7 +9570,7 @@ func (ec *executionContext) _Query_mlmdDataset(ctx context.Context, field graphq } res := resTmp.([]*graph.MlmdDataset) fc.Result = res - return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) + return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) } func (ec *executionContext) fieldContext_Query_mlmdDataset(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -14112,7 +14112,7 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o // region ***************************** type.gotpl ***************************** -func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14122,7 +14122,7 @@ func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑio return ec._Artifact(ctx, sel, v) } -func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14132,11 +14132,11 @@ func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatah return ec._ArtifactProperty(ctx, sel, v) } -func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { return ec._ArtifactType(ctx, sel, &v) } -func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14161,7 +14161,7 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14171,7 +14171,7 @@ func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑio return ec._Context(ctx, sel, v) } -func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { +func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14181,7 +14181,7 @@ func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahu return ec._ContextProperty(ctx, sel, v) } -func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { +func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14191,7 +14191,7 @@ func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑ return ec._ContextType(ctx, sel, v) } -func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { +func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14201,7 +14201,7 @@ func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋm return ec._Event(ctx, sel, v) } -func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14211,7 +14211,7 @@ func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑio return ec._Execution(ctx, sel, v) } -func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { +func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14221,7 +14221,7 @@ func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendata return ec._ExecutionProperty(ctx, sel, v) } -func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { +func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14276,7 +14276,7 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return res } -func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { +func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14301,7 +14301,7 @@ func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.S return res } -func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { +func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14311,7 +14311,7 @@ func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodel return ec._Type(ctx, sel, v) } -func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { +func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14321,7 +14321,7 @@ func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahub return ec._TypeProperty(ctx, sel, v) } -func (ec *executionContext) marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { +func (ec *executionContext) marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") @@ -14584,7 +14584,7 @@ func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel a return res } -func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14611,7 +14611,7 @@ func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑ if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14631,14 +14631,14 @@ func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑ return ret } -func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { +func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Artifact(ctx, sel, v) } -func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { +func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14665,7 +14665,7 @@ func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopenda if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14685,7 +14685,7 @@ func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopenda return ret } -func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { +func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14712,7 +14712,7 @@ func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahu if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) + ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14758,7 +14758,7 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast return res } -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14785,7 +14785,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14799,7 +14799,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi return ret } -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14826,7 +14826,7 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) + ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14846,14 +14846,14 @@ func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑi return ret } -func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { +func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Context(ctx, sel, v) } -func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { +func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14880,7 +14880,7 @@ func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendat if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14900,7 +14900,7 @@ func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendat return ret } -func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { +func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14927,7 +14927,7 @@ func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahub if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) + ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14947,7 +14947,7 @@ func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahub return ret } -func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { +func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { if v == nil { return graphql.Null } @@ -14974,7 +14974,7 @@ func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑio if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) + ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) } if isLen1 { f(i) @@ -14994,7 +14994,7 @@ func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑio return ret } -func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15021,7 +15021,7 @@ func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahub if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) + ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15041,14 +15041,14 @@ func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahub return ret } -func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { +func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { if v == nil { return graphql.Null } return ec._Execution(ctx, sel, v) } -func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { +func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15075,7 +15075,7 @@ func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopend if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15095,7 +15095,7 @@ func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopend return ret } -func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { +func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15122,7 +15122,7 @@ func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatah if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) + ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15196,7 +15196,7 @@ func (ec *executionContext) marshalOID2ᚖstring(ctx context.Context, sel ast.Se return res } -func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { +func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { if v == nil { return nil, nil } @@ -15204,7 +15204,7 @@ func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatah return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { +func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15231,7 +15231,7 @@ func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahub if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) + ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15305,7 +15305,7 @@ func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel as return res } -func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { +func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15332,7 +15332,7 @@ func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmo if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐType(ctx, sel, v[i]) + ret[i] = ec.marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐType(ctx, sel, v[i]) } if isLen1 { f(i) @@ -15352,7 +15352,7 @@ func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmo return ret } -func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { +func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { if v == nil { return nil, nil } @@ -15360,7 +15360,7 @@ func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahub return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { +func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { if v == nil { return graphql.Null } @@ -15387,7 +15387,7 @@ func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahu if !isLen1 { defer wg.Done() } - ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋpkgᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) + ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) } if isLen1 { f(i) diff --git a/pkg/server/graph/resolver.go b/internal/server/graph/resolver.go similarity index 100% rename from pkg/server/graph/resolver.go rename to internal/server/graph/resolver.go diff --git a/pkg/server/graph/schema.resolvers.go b/internal/server/graph/schema.resolvers.go similarity index 97% rename from pkg/server/graph/schema.resolvers.go rename to internal/server/graph/schema.resolvers.go index f32c7cfc..f4b6d0bc 100644 --- a/pkg/server/graph/schema.resolvers.go +++ b/internal/server/graph/schema.resolvers.go @@ -8,7 +8,7 @@ import ( "context" "fmt" - "github.com/opendatahub-io/model-registry/pkg/model/graph" + "github.com/opendatahub-io/model-registry/internal/model/graph" ) // Types is the resolver for the types field. diff --git a/pkg/server/grpc_server.go b/internal/server/grpc_server.go similarity index 67% rename from pkg/server/grpc_server.go rename to internal/server/grpc_server.go index b0deb1df..d1f90030 100644 --- a/pkg/server/grpc_server.go +++ b/internal/server/grpc_server.go @@ -3,8 +3,8 @@ package server import ( "context" "fmt" - proto2 "github.com/opendatahub-io/model-registry/pkg/ml_metadata/proto" - db2 "github.com/opendatahub-io/model-registry/pkg/model/db" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/db" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" @@ -32,20 +32,20 @@ func (tk TypeKind) String() string { } type grpcServer struct { - proto2.UnimplementedMetadataStoreServiceServer + proto.UnimplementedMetadataStoreServiceServer dbConnection *gorm.DB } -var _ proto2.MetadataStoreServiceServer = grpcServer{} -var _ proto2.MetadataStoreServiceServer = (*grpcServer)(nil) +var _ proto.MetadataStoreServiceServer = grpcServer{} +var _ proto.MetadataStoreServiceServer = (*grpcServer)(nil) -func NewGrpcServer(dbConnection *gorm.DB) proto2.MetadataStoreServiceServer { +func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { return &grpcServer{dbConnection: dbConnection} } var REQUIRED_TYPE_FIELDS = []string{"name"} -func (g grpcServer) PutArtifactType(ctx context.Context, request *proto2.PutArtifactTypeRequest) (resp *proto2.PutArtifactTypeResponse, err error) { +func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -55,7 +55,7 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto2.PutArti if err != nil { return nil, err } - value := &db2.Type{ + value := &db.Type{ Name: *artifactType.Name, Version: artifactType.Version, TypeKind: int32(ARTIFACT_TYPE), @@ -67,13 +67,13 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto2.PutArti return nil, err } var typeId = int64(value.ID) - return &proto2.PutArtifactTypeResponse{ + return &proto.PutArtifactTypeResponse{ TypeId: &typeId, }, nil } -func (g grpcServer) createOrUpdateType(ctx context.Context, value *db2.Type, - properties map[string]proto2.PropertyType) error { +func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, + properties map[string]proto.PropertyType) error { // TODO handle CanAdd, CanOmit properties from type request dbConn, _ := FromContext(ctx) @@ -88,7 +88,7 @@ func (g grpcServer) createOrUpdateType(ctx context.Context, value *db2.Type, return nil } -func (g grpcServer) PutExecutionType(ctx context.Context, request *proto2.PutExecutionTypeRequest) (resp *proto2.PutExecutionTypeResponse, err error) { +func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -97,7 +97,7 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto2.PutExe if err != nil { return nil, err } - value := &db2.Type{ + value := &db.Type{ Name: *executionType.Name, Version: executionType.Version, TypeKind: int32(EXECUTION_TYPE), @@ -109,12 +109,12 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto2.PutExe return nil, err } var typeId = int64(value.ID) - return &proto2.PutExecutionTypeResponse{ + return &proto.PutExecutionTypeResponse{ TypeId: &typeId, }, nil } -func (g grpcServer) PutContextType(ctx context.Context, request *proto2.PutContextTypeRequest) (resp *proto2.PutContextTypeResponse, err error) { +func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -123,7 +123,7 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto2.PutConte if err != nil { return nil, err } - value := &db2.Type{ + value := &db.Type{ Name: *contextType.Name, Version: contextType.Version, TypeKind: int32(CONTEXT_TYPE), @@ -138,20 +138,20 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto2.PutConte return nil, err } var typeId = int64(value.ID) - return &proto2.PutContextTypeResponse{ + return &proto.PutContextTypeResponse{ TypeId: &typeId, }, nil } -func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesRequest) (resp *proto2.PutTypesResponse, err error) { +func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest) (resp *proto.PutTypesResponse, err error) { ctx, _ = Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) - response := &proto2.PutTypesResponse{} + response := &proto.PutTypesResponse{} for _, ar := range request.ArtifactTypes { - var at *proto2.PutArtifactTypeResponse - at, err = g.PutArtifactType(ctx, &proto2.PutArtifactTypeRequest{ + var at *proto.PutArtifactTypeResponse + at, err = g.PutArtifactType(ctx, &proto.PutArtifactTypeRequest{ ArtifactType: ar, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, @@ -163,8 +163,8 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesReques response.ArtifactTypeIds = append(response.ArtifactTypeIds, *at.TypeId) } for _, ex := range request.ExecutionTypes { - var er *proto2.PutExecutionTypeResponse - er, err = g.PutExecutionType(ctx, &proto2.PutExecutionTypeRequest{ + var er *proto.PutExecutionTypeResponse + er, err = g.PutExecutionType(ctx, &proto.PutExecutionTypeRequest{ ExecutionType: ex, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, @@ -176,8 +176,8 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesReques response.ExecutionTypeIds = append(response.ExecutionTypeIds, *er.TypeId) } for _, ct := range request.ContextTypes { - var cr *proto2.PutContextTypeResponse - cr, err = g.PutContextType(ctx, &proto2.PutContextTypeRequest{ + var cr *proto.PutContextTypeResponse + cr, err = g.PutContextType(ctx, &proto.PutContextTypeRequest{ ContextType: ct, CanAddFields: request.CanAddFields, CanOmitFields: request.CanOmitFields, @@ -193,7 +193,7 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto2.PutTypesReques var REQUIRED_ARTIFACT_FIELDS = []string{"type_id", "uri"} -func (g grpcServer) PutArtifacts(ctx context.Context, request *proto2.PutArtifactsRequest) (resp *proto2.PutArtifactsResponse, err error) { +func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (resp *proto.PutArtifactsResponse, err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) @@ -203,7 +203,7 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto2.PutArtifac if err != nil { return nil, err } - value := &db2.Artifact{ + value := &db.Artifact{ TypeID: *artifact.TypeId, URI: artifact.Uri, Name: artifact.Name, @@ -227,243 +227,243 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto2.PutArtifac } artifactIds = append(artifactIds, int64(value.ID)) } - resp = &proto2.PutArtifactsResponse{ + resp = &proto.PutArtifactsResponse{ ArtifactIds: artifactIds, } return resp, nil } -func (g grpcServer) PutExecutions(ctx context.Context, request *proto2.PutExecutionsRequest) (*proto2.PutExecutionsResponse, error) { +func (g grpcServer) PutExecutions(ctx context.Context, request *proto.PutExecutionsRequest) (*proto.PutExecutionsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutEvents(ctx context.Context, request *proto2.PutEventsRequest) (*proto2.PutEventsResponse, error) { +func (g grpcServer) PutEvents(ctx context.Context, request *proto.PutEventsRequest) (*proto.PutEventsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutExecution(ctx context.Context, request *proto2.PutExecutionRequest) (*proto2.PutExecutionResponse, error) { +func (g grpcServer) PutExecution(ctx context.Context, request *proto.PutExecutionRequest) (*proto.PutExecutionResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutLineageSubgraph(ctx context.Context, request *proto2.PutLineageSubgraphRequest) (*proto2.PutLineageSubgraphResponse, error) { +func (g grpcServer) PutLineageSubgraph(ctx context.Context, request *proto.PutLineageSubgraphRequest) (*proto.PutLineageSubgraphResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutContexts(ctx context.Context, request *proto2.PutContextsRequest) (*proto2.PutContextsResponse, error) { +func (g grpcServer) PutContexts(ctx context.Context, request *proto.PutContextsRequest) (*proto.PutContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutAttributionsAndAssociations(ctx context.Context, request *proto2.PutAttributionsAndAssociationsRequest) (*proto2.PutAttributionsAndAssociationsResponse, error) { +func (g grpcServer) PutAttributionsAndAssociations(ctx context.Context, request *proto.PutAttributionsAndAssociationsRequest) (*proto.PutAttributionsAndAssociationsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) PutParentContexts(ctx context.Context, request *proto2.PutParentContextsRequest) (*proto2.PutParentContextsResponse, error) { +func (g grpcServer) PutParentContexts(ctx context.Context, request *proto.PutParentContextsRequest) (*proto.PutParentContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactType(ctx context.Context, request *proto2.GetArtifactTypeRequest) (*proto2.GetArtifactTypeResponse, error) { +func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (*proto.GetArtifactTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactTypesByID(ctx context.Context, request *proto2.GetArtifactTypesByIDRequest) (*proto2.GetArtifactTypesByIDResponse, error) { +func (g grpcServer) GetArtifactTypesByID(ctx context.Context, request *proto.GetArtifactTypesByIDRequest) (*proto.GetArtifactTypesByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactTypes(ctx context.Context, request *proto2.GetArtifactTypesRequest) (*proto2.GetArtifactTypesResponse, error) { +func (g grpcServer) GetArtifactTypes(ctx context.Context, request *proto.GetArtifactTypesRequest) (*proto.GetArtifactTypesResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionType(ctx context.Context, request *proto2.GetExecutionTypeRequest) (*proto2.GetExecutionTypeResponse, error) { +func (g grpcServer) GetExecutionType(ctx context.Context, request *proto.GetExecutionTypeRequest) (*proto.GetExecutionTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionTypesByID(ctx context.Context, request *proto2.GetExecutionTypesByIDRequest) (*proto2.GetExecutionTypesByIDResponse, error) { +func (g grpcServer) GetExecutionTypesByID(ctx context.Context, request *proto.GetExecutionTypesByIDRequest) (*proto.GetExecutionTypesByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionTypes(ctx context.Context, request *proto2.GetExecutionTypesRequest) (*proto2.GetExecutionTypesResponse, error) { +func (g grpcServer) GetExecutionTypes(ctx context.Context, request *proto.GetExecutionTypesRequest) (*proto.GetExecutionTypesResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextType(ctx context.Context, request *proto2.GetContextTypeRequest) (*proto2.GetContextTypeResponse, error) { +func (g grpcServer) GetContextType(ctx context.Context, request *proto.GetContextTypeRequest) (*proto.GetContextTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextTypesByID(ctx context.Context, request *proto2.GetContextTypesByIDRequest) (*proto2.GetContextTypesByIDResponse, error) { +func (g grpcServer) GetContextTypesByID(ctx context.Context, request *proto.GetContextTypesByIDRequest) (*proto.GetContextTypesByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextTypes(ctx context.Context, request *proto2.GetContextTypesRequest) (*proto2.GetContextTypesResponse, error) { +func (g grpcServer) GetContextTypes(ctx context.Context, request *proto.GetContextTypesRequest) (*proto.GetContextTypesResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifacts(ctx context.Context, request *proto2.GetArtifactsRequest) (*proto2.GetArtifactsResponse, error) { +func (g grpcServer) GetArtifacts(ctx context.Context, request *proto.GetArtifactsRequest) (*proto.GetArtifactsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutions(ctx context.Context, request *proto2.GetExecutionsRequest) (*proto2.GetExecutionsResponse, error) { +func (g grpcServer) GetExecutions(ctx context.Context, request *proto.GetExecutionsRequest) (*proto.GetExecutionsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContexts(ctx context.Context, request *proto2.GetContextsRequest) (*proto2.GetContextsResponse, error) { +func (g grpcServer) GetContexts(ctx context.Context, request *proto.GetContextsRequest) (*proto.GetContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByID(ctx context.Context, request *proto2.GetArtifactsByIDRequest) (*proto2.GetArtifactsByIDResponse, error) { +func (g grpcServer) GetArtifactsByID(ctx context.Context, request *proto.GetArtifactsByIDRequest) (*proto.GetArtifactsByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByID(ctx context.Context, request *proto2.GetExecutionsByIDRequest) (*proto2.GetExecutionsByIDResponse, error) { +func (g grpcServer) GetExecutionsByID(ctx context.Context, request *proto.GetExecutionsByIDRequest) (*proto.GetExecutionsByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByID(ctx context.Context, request *proto2.GetContextsByIDRequest) (*proto2.GetContextsByIDResponse, error) { +func (g grpcServer) GetContextsByID(ctx context.Context, request *proto.GetContextsByIDRequest) (*proto.GetContextsByIDResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByType(ctx context.Context, request *proto2.GetArtifactsByTypeRequest) (*proto2.GetArtifactsByTypeResponse, error) { +func (g grpcServer) GetArtifactsByType(ctx context.Context, request *proto.GetArtifactsByTypeRequest) (*proto.GetArtifactsByTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByType(ctx context.Context, request *proto2.GetExecutionsByTypeRequest) (*proto2.GetExecutionsByTypeResponse, error) { +func (g grpcServer) GetExecutionsByType(ctx context.Context, request *proto.GetExecutionsByTypeRequest) (*proto.GetExecutionsByTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByType(ctx context.Context, request *proto2.GetContextsByTypeRequest) (*proto2.GetContextsByTypeResponse, error) { +func (g grpcServer) GetContextsByType(ctx context.Context, request *proto.GetContextsByTypeRequest) (*proto.GetContextsByTypeResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactByTypeAndName(ctx context.Context, request *proto2.GetArtifactByTypeAndNameRequest) (*proto2.GetArtifactByTypeAndNameResponse, error) { +func (g grpcServer) GetArtifactByTypeAndName(ctx context.Context, request *proto.GetArtifactByTypeAndNameRequest) (*proto.GetArtifactByTypeAndNameResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionByTypeAndName(ctx context.Context, request *proto2.GetExecutionByTypeAndNameRequest) (*proto2.GetExecutionByTypeAndNameResponse, error) { +func (g grpcServer) GetExecutionByTypeAndName(ctx context.Context, request *proto.GetExecutionByTypeAndNameRequest) (*proto.GetExecutionByTypeAndNameResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextByTypeAndName(ctx context.Context, request *proto2.GetContextByTypeAndNameRequest) (*proto2.GetContextByTypeAndNameResponse, error) { +func (g grpcServer) GetContextByTypeAndName(ctx context.Context, request *proto.GetContextByTypeAndNameRequest) (*proto.GetContextByTypeAndNameResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByURI(ctx context.Context, request *proto2.GetArtifactsByURIRequest) (*proto2.GetArtifactsByURIResponse, error) { +func (g grpcServer) GetArtifactsByURI(ctx context.Context, request *proto.GetArtifactsByURIRequest) (*proto.GetArtifactsByURIResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetEventsByExecutionIDs(ctx context.Context, request *proto2.GetEventsByExecutionIDsRequest) (*proto2.GetEventsByExecutionIDsResponse, error) { +func (g grpcServer) GetEventsByExecutionIDs(ctx context.Context, request *proto.GetEventsByExecutionIDsRequest) (*proto.GetEventsByExecutionIDsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetEventsByArtifactIDs(ctx context.Context, request *proto2.GetEventsByArtifactIDsRequest) (*proto2.GetEventsByArtifactIDsResponse, error) { +func (g grpcServer) GetEventsByArtifactIDs(ctx context.Context, request *proto.GetEventsByArtifactIDsRequest) (*proto.GetEventsByArtifactIDsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByExternalIds(ctx context.Context, request *proto2.GetArtifactsByExternalIdsRequest) (*proto2.GetArtifactsByExternalIdsResponse, error) { +func (g grpcServer) GetArtifactsByExternalIds(ctx context.Context, request *proto.GetArtifactsByExternalIdsRequest) (*proto.GetArtifactsByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByExternalIds(ctx context.Context, request *proto2.GetExecutionsByExternalIdsRequest) (*proto2.GetExecutionsByExternalIdsResponse, error) { +func (g grpcServer) GetExecutionsByExternalIds(ctx context.Context, request *proto.GetExecutionsByExternalIdsRequest) (*proto.GetExecutionsByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByExternalIds(ctx context.Context, request *proto2.GetContextsByExternalIdsRequest) (*proto2.GetContextsByExternalIdsResponse, error) { +func (g grpcServer) GetContextsByExternalIds(ctx context.Context, request *proto.GetContextsByExternalIdsRequest) (*proto.GetContextsByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactTypesByExternalIds(ctx context.Context, request *proto2.GetArtifactTypesByExternalIdsRequest) (*proto2.GetArtifactTypesByExternalIdsResponse, error) { +func (g grpcServer) GetArtifactTypesByExternalIds(ctx context.Context, request *proto.GetArtifactTypesByExternalIdsRequest) (*proto.GetArtifactTypesByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionTypesByExternalIds(ctx context.Context, request *proto2.GetExecutionTypesByExternalIdsRequest) (*proto2.GetExecutionTypesByExternalIdsResponse, error) { +func (g grpcServer) GetExecutionTypesByExternalIds(ctx context.Context, request *proto.GetExecutionTypesByExternalIdsRequest) (*proto.GetExecutionTypesByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextTypesByExternalIds(ctx context.Context, request *proto2.GetContextTypesByExternalIdsRequest) (*proto2.GetContextTypesByExternalIdsResponse, error) { +func (g grpcServer) GetContextTypesByExternalIds(ctx context.Context, request *proto.GetContextTypesByExternalIdsRequest) (*proto.GetContextTypesByExternalIdsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByArtifact(ctx context.Context, request *proto2.GetContextsByArtifactRequest) (*proto2.GetContextsByArtifactResponse, error) { +func (g grpcServer) GetContextsByArtifact(ctx context.Context, request *proto.GetContextsByArtifactRequest) (*proto.GetContextsByArtifactResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetContextsByExecution(ctx context.Context, request *proto2.GetContextsByExecutionRequest) (*proto2.GetContextsByExecutionResponse, error) { +func (g grpcServer) GetContextsByExecution(ctx context.Context, request *proto.GetContextsByExecutionRequest) (*proto.GetContextsByExecutionResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetParentContextsByContext(ctx context.Context, request *proto2.GetParentContextsByContextRequest) (*proto2.GetParentContextsByContextResponse, error) { +func (g grpcServer) GetParentContextsByContext(ctx context.Context, request *proto.GetParentContextsByContextRequest) (*proto.GetParentContextsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetChildrenContextsByContext(ctx context.Context, request *proto2.GetChildrenContextsByContextRequest) (*proto2.GetChildrenContextsByContextResponse, error) { +func (g grpcServer) GetChildrenContextsByContext(ctx context.Context, request *proto.GetChildrenContextsByContextRequest) (*proto.GetChildrenContextsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetParentContextsByContexts(ctx context.Context, request *proto2.GetParentContextsByContextsRequest) (*proto2.GetParentContextsByContextsResponse, error) { +func (g grpcServer) GetParentContextsByContexts(ctx context.Context, request *proto.GetParentContextsByContextsRequest) (*proto.GetParentContextsByContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetChildrenContextsByContexts(ctx context.Context, request *proto2.GetChildrenContextsByContextsRequest) (*proto2.GetChildrenContextsByContextsResponse, error) { +func (g grpcServer) GetChildrenContextsByContexts(ctx context.Context, request *proto.GetChildrenContextsByContextsRequest) (*proto.GetChildrenContextsByContextsResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetArtifactsByContext(ctx context.Context, request *proto2.GetArtifactsByContextRequest) (*proto2.GetArtifactsByContextResponse, error) { +func (g grpcServer) GetArtifactsByContext(ctx context.Context, request *proto.GetArtifactsByContextRequest) (*proto.GetArtifactsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetExecutionsByContext(ctx context.Context, request *proto2.GetExecutionsByContextRequest) (*proto2.GetExecutionsByContextResponse, error) { +func (g grpcServer) GetExecutionsByContext(ctx context.Context, request *proto.GetExecutionsByContextRequest) (*proto.GetExecutionsByContextResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetLineageGraph(ctx context.Context, request *proto2.GetLineageGraphRequest) (*proto2.GetLineageGraphResponse, error) { +func (g grpcServer) GetLineageGraph(ctx context.Context, request *proto.GetLineageGraphRequest) (*proto.GetLineageGraphResponse, error) { //TODO implement me panic("implement me") } -func (g grpcServer) GetLineageSubgraph(ctx context.Context, request *proto2.GetLineageSubgraphRequest) (*proto2.GetLineageSubgraphResponse, error) { +func (g grpcServer) GetLineageSubgraph(ctx context.Context, request *proto.GetLineageSubgraphRequest) (*proto.GetLineageSubgraphResponse, error) { //TODO implement me panic("implement me") } @@ -473,13 +473,13 @@ func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { // implemented to signal that server is extendable } -func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto2.PropertyType, typeId int64) (err error) { +func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, typeId int64) (err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { number := int32(prop.Number()) - property := &db2.TypeProperty{ + property := &db.TypeProperty{ TypeID: typeId, Name: propName, DataType: number, @@ -493,12 +493,12 @@ func (g grpcServer) createTypeProperties(ctx context.Context, properties map[str return nil } -func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto2.Value, isCustomProperty bool) (err error) { +func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto.Value, isCustomProperty bool) (err error) { ctx, dbConn := Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { - property := &db2.ArtifactProperty{ + property := &db.ArtifactProperty{ ArtifactID: artifactId, Name: propName, } @@ -506,19 +506,19 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int property.IsCustomProperty = true } // TODO handle polymorphic value with null columns - intValue, ok := prop.GetValue().(*proto2.Value_IntValue) + intValue, ok := prop.GetValue().(*proto.Value_IntValue) if ok { property.IntValue = &intValue.IntValue } - doubleValue, ok := prop.GetValue().(*proto2.Value_DoubleValue) + doubleValue, ok := prop.GetValue().(*proto.Value_DoubleValue) if ok { property.DoubleValue = &doubleValue.DoubleValue } - stringValue, ok := prop.GetValue().(*proto2.Value_StringValue) + stringValue, ok := prop.GetValue().(*proto.Value_StringValue) if ok { property.StringValue = &stringValue.StringValue } - structValue, ok := prop.GetValue().(*proto2.Value_StructValue) + structValue, ok := prop.GetValue().(*proto.Value_StructValue) if ok { json, err2 := structValue.StructValue.MarshalJSON() if err2 != nil { @@ -527,11 +527,11 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int } property.ByteValue = &json } - protoValue, ok := prop.GetValue().(*proto2.Value_ProtoValue) + protoValue, ok := prop.GetValue().(*proto.Value_ProtoValue) if ok { property.ProtoValue = &protoValue.ProtoValue.Value } - boolValue, ok := prop.GetValue().(*proto2.Value_BoolValue) + boolValue, ok := prop.GetValue().(*proto.Value_BoolValue) if ok { property.BoolValue = &boolValue.BoolValue } @@ -544,7 +544,7 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int } func identity[T int64 | string](i T) T { return i } -func artifactStateToInt64(i proto2.Artifact_State) *int64 { +func artifactStateToInt64(i proto.Artifact_State) *int64 { var result = int64(i) return &result } @@ -562,7 +562,7 @@ func requiredFields(names []string, args ...interface{}) error { return nil } -func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto2.Artifact_State | string](dest *D, src *S, f func(i S) D) { +func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { if src != nil { *dest = f(*src) } From bba97d276ef3725d69726bb44ee763b36eca0af2 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 20 Sep 2023 09:17:25 -0700 Subject: [PATCH 036/254] Refactored metadata_library Moved library file loading into metadata_library.go to make it reusable for future tools like graphql schema generator. --- cmd/migrate.go | 114 ++++++++------------- internal/model/library/metadata_library.go | 54 ++++++++-- 2 files changed, 91 insertions(+), 77 deletions(-) diff --git a/cmd/migrate.go b/cmd/migrate.go index 43d68a18..ed6b195e 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -24,12 +24,7 @@ import ( "github.com/opendatahub-io/model-registry/internal/model/library" "github.com/opendatahub-io/model-registry/internal/server" "github.com/spf13/cobra" - "gopkg.in/yaml.v3" "gorm.io/gorm" - "io/fs" - "os" - "path/filepath" - "strings" ) // migrateCmd represents the migrate command @@ -96,80 +91,57 @@ func migrateDatabase(dbConn *gorm.DB) error { } func loadLibraries(dbConn *gorm.DB) error { - for _, dir := range libraryDirs { - abs, err := filepath.Abs(dir) - if err != nil { - return fmt.Errorf("error getting absolute library path for %s: %w", dir, err) + libs, err := library.LoadLibraries(libraryDirs) + if err != nil { + return fmt.Errorf("failed to read library directories %s: %w", libraryDirs, err) + } + for path, lib := range libs { + grpcServer := server.NewGrpcServer(dbConn) + typesRequest := proto.PutTypesRequest{} + for _, at := range lib.ArtifactTypes { + typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ + Name: at.Name, + Version: at.Version, + Description: at.Description, + ExternalId: at.ExternalId, + Properties: ToProtoProperties(at.Properties), + }) } - _, err = os.Stat(abs) - if err != nil { - return fmt.Errorf("error opening library path for %s: %w", abs, err) + for _, ct := range lib.ContextTypes { + typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ + Name: ct.Name, + Version: ct.Version, + Description: ct.Description, + ExternalId: ct.ExternalId, + Properties: ToProtoProperties(ct.Properties), + }) } - err = filepath.WalkDir(abs, func(path string, entry fs.DirEntry, err error) error { - if err != nil { - glog.Warningf("error reading library path %s: %v", path, err) - return filepath.SkipDir - } - if entry.IsDir() || !isYamlFile(path) { - return nil - } - - bytes, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("failed to read library file %s: %w", path, err) - } - var lib library.MetadataLibrary - err = yaml.Unmarshal(bytes, &lib) - if err != nil { - return fmt.Errorf("failed to parse library file %s: %w", path, err) - } - grpcServer := server.NewGrpcServer(dbConn) - typesRequest := proto.PutTypesRequest{} - for _, at := range lib.ArtifactTypes { - typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ - Name: at.Name, - Version: at.Version, - Description: at.Description, - ExternalId: at.ExternalId, - Properties: library.ToProtoProperties(at.Properties), - }) - } - for _, ct := range lib.ContextTypes { - typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ - Name: ct.Name, - Version: ct.Version, - Description: ct.Description, - ExternalId: ct.ExternalId, - Properties: library.ToProtoProperties(ct.Properties), - }) - } - for _, et := range lib.ExecutionTypes { - typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ - Name: et.Name, - Version: et.Version, - Description: et.Description, - ExternalId: et.ExternalId, - Properties: library.ToProtoProperties(et.Properties), - }) - } - response, err := grpcServer.PutTypes(context.Background(), &typesRequest) - if err != nil { - return fmt.Errorf("failed to add library from file %s: %w", path, err) - } - glog.Infof("created/updated %d artifacts, %d contexts and %d execution types from library file %s", - len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) - return nil - }) + for _, et := range lib.ExecutionTypes { + typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ + Name: et.Name, + Version: et.Version, + Description: et.Description, + ExternalId: et.ExternalId, + Properties: ToProtoProperties(et.Properties), + }) + } + response, err := grpcServer.PutTypes(context.Background(), &typesRequest) if err != nil { - return fmt.Errorf("failed to read library directory %s: %w", abs, err) + return fmt.Errorf("failed to add library from file %s: %w", path, err) } + glog.Infof("created/updated %d ArtifactTypes, %d ContextTypes and %d ExecutionTypes from library file %s", + len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) + return nil } return nil } -func isYamlFile(path string) bool { - lowerPath := strings.ToLower(filepath.Ext(path)) - return strings.HasSuffix(lowerPath, ".yaml") || strings.HasSuffix(lowerPath, ".yml") +func ToProtoProperties(props map[string]library.PropertyType) map[string]proto.PropertyType { + result := make(map[string]proto.PropertyType) + for name, prop := range props { + result[name] = proto.PropertyType(prop) + } + return result } var libraryDirs []string diff --git a/internal/model/library/metadata_library.go b/internal/model/library/metadata_library.go index 7fb1c06c..7ce2c84d 100644 --- a/internal/model/library/metadata_library.go +++ b/internal/model/library/metadata_library.go @@ -1,7 +1,13 @@ package library import ( - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "fmt" + "github.com/golang/glog" + "gopkg.in/yaml.v3" + "io/fs" + "os" + "path/filepath" + "strings" ) //go:generate go-enum -type=PropertyType @@ -49,10 +55,46 @@ type MetadataLibrary struct { ExecutionTypes []ExecutionType `yaml:"execution-types,omitempty"` } -func ToProtoProperties(props map[string]PropertyType) map[string]proto.PropertyType { - result := make(map[string]proto.PropertyType) - for name, prop := range props { - result[name] = proto.PropertyType(prop) +func LoadLibraries(dirs []string) (map[string]*MetadataLibrary, error) { + result := make(map[string]*MetadataLibrary) + for _, dir := range dirs { + abs, err := filepath.Abs(dir) + if err != nil { + return nil, fmt.Errorf("error getting absolute library path for %s: %w", dir, err) + } + _, err = os.Stat(abs) + if err != nil { + return nil, fmt.Errorf("error opening library path for %s: %w", abs, err) + } + err = filepath.WalkDir(abs, func(path string, entry fs.DirEntry, err error) error { + if err != nil { + glog.Warningf("error reading library path %s: %v", path, err) + return filepath.SkipDir + } + if entry.IsDir() || !isYamlFile(path) { + return nil + } + + bytes, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed to read library file %s: %w", path, err) + } + lib := &MetadataLibrary{} + err = yaml.Unmarshal(bytes, lib) + if err != nil { + return fmt.Errorf("failed to parse library file %s: %w", path, err) + } + result[path] = lib + return nil + }) + if err != nil { + return nil, fmt.Errorf("failed to read library directory %s: %w", abs, err) + } } - return result + return result, nil +} + +func isYamlFile(path string) bool { + lowerPath := strings.ToLower(filepath.Ext(path)) + return strings.HasSuffix(lowerPath, ".yaml") || strings.HasSuffix(lowerPath, ".yml") } From a73c7a6d8168676aaf3f2a701615457eda3a6109 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 20 Sep 2023 09:24:31 -0700 Subject: [PATCH 037/254] Removed generated gRPC go model in .gitignore Generated go files should be checked in. This will make it possible for CI to detect whether gen/grpc was run before merging PRs. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index a2bdd65d..e9ecdf6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ .idea .model-registry.yaml model-registry -ml_metadata/proto/*.go metadata.sqlite.db vendor From 11f7d397c72ae2345cb31ca05d6b151a5d3950b3 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 20 Sep 2023 15:01:53 -0700 Subject: [PATCH 038/254] Update issue templates Add standard github templates for creating issues. --- .github/ISSUE_TEMPLATE/bug_report.md | 23 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/chore.md | 8 ++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/chore.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..df000f1f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,23 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Do this '...' +2. Do that '....' +3. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/chore.md b/.github/ISSUE_TEMPLATE/chore.md new file mode 100644 index 00000000..d13b9a18 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/chore.md @@ -0,0 +1,8 @@ +--- +name: Chore issue template +about: General purpose issues related to chores, project management, etc. +title: '' +labels: '' +assignees: '' + +--- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 3300cd8a69f090a54a346ca9c22f83f6180f3fd1 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 20 Sep 2023 16:28:11 -0700 Subject: [PATCH 039/254] Add labels to issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/chore.md | 2 +- .github/ISSUE_TEMPLATE/feature_request.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index df000f1f..f3ecdb83 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve title: '' -labels: '' +labels: 'bug' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/chore.md b/.github/ISSUE_TEMPLATE/chore.md index d13b9a18..24fc1b72 100644 --- a/.github/ISSUE_TEMPLATE/chore.md +++ b/.github/ISSUE_TEMPLATE/chore.md @@ -2,7 +2,7 @@ name: Chore issue template about: General purpose issues related to chores, project management, etc. title: '' -labels: '' +labels: 'chore' assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7d..de666bae 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -2,7 +2,7 @@ name: Feature request about: Suggest an idea for this project title: '' -labels: '' +labels: 'feature' assignees: '' --- From 8809d3e23eed6e89e49f94a47128e649eeb2a9da Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Thu, 21 Sep 2023 07:12:42 +0000 Subject: [PATCH 040/254] adding PR template per discussion --- .github/pull_request_template.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..07da810b --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,17 @@ + + +## Description + + +## How Has This Been Tested? + + + + +## Merge criteria: + + + +- [ ] The commits and have meaningful messages; the author will squash them [after approval](https://github.com/opendatahub-io/opendatahub-community/blob/main/contributor-cheatsheet.md#:~:text=Usually%20this%20is%20done%20in%20last%20phase%20of%20a%20PR%20revision) or will ask to merge with squash. +- [ ] Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious). +- [ ] The developer has manually tested the changes and verified that the changes work From 5f25946c778ca5188d9dd62a44b1fbd2929dc631 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Fri, 22 Sep 2023 17:32:05 +0200 Subject: [PATCH 041/254] Reproducible builds (#6) 1. use makefile to automate deps install 2. setup basic GHA to ensure makefile build is reproducible --- .github/workflows/build.yml | 31 +++++++++++++++++++++++++++++++ Makefile | 8 ++++++++ 2 files changed, 39 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..7f4040e0 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,31 @@ +name: Build + +on: + push: + branches: [ 'main' ] + pull_request: + branches: [ '*' ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Go + uses: actions/setup-go@v4 + with: + go-version: '1.19' + - name: Install Protoc + uses: arduino/setup-protoc@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: 3.9 + - name: Install makefile dependencies + run: make deps + - name: Clean + run: make clean + - name: Build + run: make build diff --git a/Makefile b/Makefile index 1fdd8ba3..881ce1fc 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,14 @@ vet: clean: rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/*.go +.PHONY: deps +deps: + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin v1.54.2 + go install github.com/99designs/gqlgen@latest + go install github.com/searKing/golang/tools/go-enum@latest + go install google.golang.org/protobuf/cmd/protoc-gen-go@latest + go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + .PHONY: vendor vendor: go mod vendor From ca80c2466426047f809dfd0e432baa60dd3fd51c Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 22 Sep 2023 16:42:57 +0200 Subject: [PATCH 042/254] Serve correct grpc listener --- cmd/serve.go | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/cmd/serve.go b/cmd/serve.go index 5878bcb7..cde07589 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -18,6 +18,13 @@ package cmd import ( "context" "fmt" + "log" + "net" + "net/http" + "os" + "os/signal" + "syscall" + "github.com/99designs/gqlgen/graphql/handler" "github.com/99designs/gqlgen/graphql/playground" "github.com/golang/glog" @@ -34,12 +41,6 @@ import ( "google.golang.org/grpc/reflection" "gorm.io/driver/sqlite" "gorm.io/gorm" - "log" - "net" - "net/http" - "os" - "os/signal" - "syscall" ) func InterceptorLogger(l *log.Logger) logging.Logger { @@ -102,15 +103,15 @@ func runServer(cmd *cobra.Command, args []string) error { grpcListener := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) // gRPC server - grpcServer := grpcListenerServer(grpcListener, server.NewGrpcServer(db)) + grpcServer := grpcListenerServer(server.NewGrpcServer(db)) // GraphQL server - gqlServer := graphQlListenerServer(grpcListener, db) + gqlServer := graphQlListenerServer(db) // start cmux listeners g := new(errgroup.Group) g.Go(func() error { glog.Info("starting gRPC server...") - return grpcServer.Serve(listener) + return grpcServer.Serve(grpcListener) }) g.Go(func() error { glog.Info("starting GraphQL server...") @@ -152,7 +153,7 @@ func runServer(cmd *cobra.Command, args []string) error { return nil } -func graphQlListenerServer(listener net.Listener, db *gorm.DB) *http.Server { +func graphQlListenerServer(db *gorm.DB) *http.Server { mux := http.NewServeMux() srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})) @@ -162,7 +163,7 @@ func graphQlListenerServer(listener net.Listener, db *gorm.DB) *http.Server { return &http.Server{Handler: mux} } -func grpcListenerServer(listener net.Listener, server proto.MetadataStoreServiceServer) *grpc.Server { +func grpcListenerServer(server proto.MetadataStoreServiceServer) *grpc.Server { // TODO map server options from flags logger := log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile) lopts := []logging.Option{ From 0ac30c6b386acb41846fbf5ab88c7d84db25642d Mon Sep 17 00:00:00 2001 From: tarilabs Date: Mon, 25 Sep 2023 09:00:49 +0200 Subject: [PATCH 043/254] Avoid repeated nil check --- internal/server/grpc_server.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/server/grpc_server.go b/internal/server/grpc_server.go index d1f90030..f2617659 100644 --- a/internal/server/grpc_server.go +++ b/internal/server/grpc_server.go @@ -3,6 +3,7 @@ package server import ( "context" "fmt" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/db" "google.golang.org/grpc/codes" @@ -134,9 +135,6 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex if err != nil { return nil, err } - if err != nil { - return nil, err - } var typeId = int64(value.ID) return &proto.PutContextTypeResponse{ TypeId: &typeId, From 7293d51cf3fa2316ce6f3c2407a5118aa8377a1a Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Wed, 27 Sep 2023 11:51:57 +0200 Subject: [PATCH 044/254] Implement gRPC GetArtifactType (#26) * Implement gRPC GetArtifactType * Add test client code to current prototype IT --- internal/server/grpc_server.go | 35 +++++++++++++++++++++++++++++++--- test/python/test_mlmetadata.py | 6 ++++++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/internal/server/grpc_server.go b/internal/server/grpc_server.go index f2617659..00b401b2 100644 --- a/internal/server/grpc_server.go +++ b/internal/server/grpc_server.go @@ -266,9 +266,38 @@ func (g grpcServer) PutParentContexts(ctx context.Context, request *proto.PutPar panic("implement me") } -func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (*proto.GetArtifactTypeResponse, error) { - //TODO implement me - panic("implement me") +func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (resp *proto.GetArtifactTypeResponse, err error) { + ctx, dbConn := Begin(ctx, g.dbConnection) + defer handleTransaction(ctx, &err) + + err = requiredFields(REQUIRED_TYPE_FIELDS, request.TypeName) + response := &proto.GetArtifactTypeResponse{} + + var results []db.Type + rx := dbConn.Find(&results, db.Type{Name: *request.TypeName, TypeKind: int32(ARTIFACT_TYPE), Version: request.TypeVersion}) + if rx.Error != nil { + return nil, rx.Error + } + if len(results) > 1 { + return nil, fmt.Errorf("more than one type found: %v", len(results)) + } + if len(results) == 0 { + return response, nil + } + + r0 := results[0] + artifactType := proto.ArtifactType{ + Id: &r0.ID, + Name: &r0.Name, + Version: r0.Version, + Description: r0.Description, + ExternalId: r0.ExternalID, + } + for _, v := range r0.Properties { + artifactType.Properties[v.Name] = proto.PropertyType(v.DataType) + } + response.ArtifactType = &artifactType + return response, nil } func (g grpcServer) GetArtifactTypesByID(ctx context.Context, request *proto.GetArtifactTypesByIDRequest) (*proto.GetArtifactTypesByIDResponse, error) { diff --git a/test/python/test_mlmetadata.py b/test/python/test_mlmetadata.py index aa018b3c..d01bc3ba 100644 --- a/test/python/test_mlmetadata.py +++ b/test/python/test_mlmetadata.py @@ -45,6 +45,12 @@ def main(): response = store.PutArtifactType(request) model_type_id = response.type_id + request = metadata_store_service_pb2.GetArtifactTypeRequest() + request.type_name = "SavedModel" + response = store.GetArtifactType(request) + assert response.artifact_type.id == 2 + assert response.artifact_type.name == "SavedModel" + # Query all registered Artifact types. # artifact_types = store.GetArtifactTypes() From b844d9135be59a30eaa2f18cd55acd0826958233 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 19 Sep 2023 17:31:01 -0700 Subject: [PATCH 045/254] Fixes #35, refactor DB schema Add missing indexes Constraints for keys Associations Use appropriate column sizes for numeric types Set creation and modification timestamps automatically using gorm tags Clean up Makefile to install pinned deps in ./bin --- Makefile | 21 ++-- bin/.gitignore | 4 + cmd/migrate.go | 5 +- cmd/serve.go | 4 +- internal/model/db/artifact.gen.go | 30 ------ internal/model/db/artifact.go | 52 +++++++++ internal/model/db/artifactproperty.gen.go | 25 ----- internal/model/db/artifactproperty.go | 102 ++++++++++++++++++ .../db/{association.gen.go => association.go} | 4 - .../db/{attribution.gen.go => attribution.go} | 4 - .../model/db/{context.gen.go => context.go} | 8 +- internal/model/db/contextproperty.gen.go | 25 ----- internal/model/db/contextproperty.go | 102 ++++++++++++++++++ internal/model/db/event.gen.go | 25 ----- internal/model/db/event.go | 39 +++++++ .../db/{eventpath.gen.go => eventpath.go} | 6 +- .../db/{execution.gen.go => execution.go} | 22 ++-- internal/model/db/executionproperty.gen.go | 25 ----- internal/model/db/executionproperty.go | 102 ++++++++++++++++++ .../model/db/{mlmdenv.gen.go => mlmdenv.go} | 4 - ...{parentcontext.gen.go => parentcontext.go} | 4 - .../db/{parenttype.gen.go => parenttype.go} | 4 - internal/model/db/property_interface.go | 24 +++++ internal/model/db/type.gen.go | 27 ----- internal/model/db/type.go | 32 ++++++ .../{typeproperty.gen.go => typeproperty.go} | 4 - internal/server/{ => grpc}/grpc_server.go | 65 ++++------- 27 files changed, 515 insertions(+), 254 deletions(-) create mode 100644 bin/.gitignore delete mode 100644 internal/model/db/artifact.gen.go create mode 100644 internal/model/db/artifact.go delete mode 100644 internal/model/db/artifactproperty.gen.go create mode 100644 internal/model/db/artifactproperty.go rename internal/model/db/{association.gen.go => association.go} (80%) rename internal/model/db/{attribution.gen.go => attribution.go} (80%) rename internal/model/db/{context.gen.go => context.go} (81%) delete mode 100644 internal/model/db/contextproperty.gen.go create mode 100644 internal/model/db/contextproperty.go delete mode 100644 internal/model/db/event.gen.go create mode 100644 internal/model/db/event.go rename internal/model/db/{eventpath.gen.go => eventpath.go} (69%) rename internal/model/db/{execution.gen.go => execution.go} (68%) delete mode 100644 internal/model/db/executionproperty.gen.go create mode 100644 internal/model/db/executionproperty.go rename internal/model/db/{mlmdenv.gen.go => mlmdenv.go} (66%) rename internal/model/db/{parentcontext.gen.go => parentcontext.go} (76%) rename internal/model/db/{parenttype.gen.go => parenttype.go} (72%) create mode 100644 internal/model/db/property_interface.go delete mode 100644 internal/model/db/type.gen.go create mode 100644 internal/model/db/type.go rename internal/model/db/{typeproperty.gen.go => typeproperty.go} (75%) rename internal/server/{ => grpc}/grpc_server.go (94%) diff --git a/Makefile b/Makefile index 881ce1fc..90739775 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,10 @@ +# useful paths +MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) +PROJECT_PATH := $(patsubst %/,%,$(dir $(MKFILE_PATH))) +PROJECT_BIN := $(PROJECT_PATH)/bin + +# add tools bin directory +PATH := $(PROJECT_BIN):$(PATH) model-registry: build internal/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto @@ -19,15 +26,15 @@ vet: .PHONY: clean clean: - rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/*.go + rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go .PHONY: deps deps: - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $$(go env GOPATH)/bin v1.54.2 - go install github.com/99designs/gqlgen@latest - go install github.com/searKing/golang/tools/go-enum@latest - go install google.golang.org/protobuf/cmd/protoc-gen-go@latest - go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.54.2 + GOBIN=$(PROJECT_BIN) go install github.com/99designs/gqlgen@v0.17.36 + GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 + GOBIN=$(PROJECT_BIN) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 + GOBIN=$(PROJECT_BIN) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 .PHONY: vendor vendor: @@ -48,7 +55,7 @@ lint: gen .PHONY: run/migrate run/migrate: gen - go run main.go migrate --logtostderr=true + go run main.go migrate --logtostderr=true -m config/metadata-library metadata.sqlite.db: run/migrate diff --git a/bin/.gitignore b/bin/.gitignore new file mode 100644 index 00000000..5e7d2734 --- /dev/null +++ b/bin/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/cmd/migrate.go b/cmd/migrate.go index ed6b195e..85106f1e 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -22,7 +22,7 @@ import ( "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/db" "github.com/opendatahub-io/model-registry/internal/model/library" - "github.com/opendatahub-io/model-registry/internal/server" + "github.com/opendatahub-io/model-registry/internal/server/grpc" "github.com/spf13/cobra" "gorm.io/gorm" ) @@ -96,7 +96,7 @@ func loadLibraries(dbConn *gorm.DB) error { return fmt.Errorf("failed to read library directories %s: %w", libraryDirs, err) } for path, lib := range libs { - grpcServer := server.NewGrpcServer(dbConn) + grpcServer := grpc.NewGrpcServer(dbConn) typesRequest := proto.PutTypesRequest{} for _, at := range lib.ArtifactTypes { typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ @@ -131,7 +131,6 @@ func loadLibraries(dbConn *gorm.DB) error { } glog.Infof("created/updated %d ArtifactTypes, %d ContextTypes and %d ExecutionTypes from library file %s", len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) - return nil } return nil } diff --git a/cmd/serve.go b/cmd/serve.go index cde07589..bb5e0ee4 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -18,6 +18,7 @@ package cmd import ( "context" "fmt" + grpc2 "github.com/opendatahub-io/model-registry/internal/server/grpc" "log" "net" "net/http" @@ -30,7 +31,6 @@ import ( "github.com/golang/glog" "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/server" "github.com/opendatahub-io/model-registry/internal/server/graph" "github.com/soheilhy/cmux" "github.com/spf13/cobra" @@ -103,7 +103,7 @@ func runServer(cmd *cobra.Command, args []string) error { grpcListener := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) // gRPC server - grpcServer := grpcListenerServer(server.NewGrpcServer(db)) + grpcServer := grpcListenerServer(grpc2.NewGrpcServer(db)) // GraphQL server gqlServer := graphQlListenerServer(db) diff --git a/internal/model/db/artifact.gen.go b/internal/model/db/artifact.gen.go deleted file mode 100644 index 7545c277..00000000 --- a/internal/model/db/artifact.gen.go +++ /dev/null @@ -1,30 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package db - -const TableNameArtifact = "Artifact" - -// Artifact mapped from table -type Artifact struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueArtifactTypeName,priority:1" json:"-"` - URI *string `gorm:"column:uri;index:idx_artifact_uri,priority:1" json:"-"` - State *int64 `gorm:"column:state" json:"-"` - Name *string `gorm:"column:name;uniqueIndex:UniqueArtifactTypeName,priority:2" json:"-"` - ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_artifact_external_id,priority:1" json:"-"` - CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_artifact_create_time_since_epoch,priority:1" json:"-"` - LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_artifact_last_update_time_since_epoch,priority:1" json:"-"` - - // relationships - Properties []ArtifactProperty - ArtifactType Type `gorm:"foreignKey:TypeID;references:ID"` - Attributions []Attribution `gorm:"foreignKey:ArtifactID;references:ID"` - Events []Event -} - -// TableName Artifact's table name -func (*Artifact) TableName() string { - return TableNameArtifact -} diff --git a/internal/model/db/artifact.go b/internal/model/db/artifact.go new file mode 100644 index 00000000..7efefd58 --- /dev/null +++ b/internal/model/db/artifact.go @@ -0,0 +1,52 @@ +package db + +const TableNameArtifact = "Artifact" + +// Artifact mapped from table +type Artifact struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` + TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueArtifactTypeName,priority:1" json:"-"` + URI *string `gorm:"column:uri;type:text;index:idx_artifact_uri,priority:1" json:"-"` + State *int8 `gorm:"column:state" json:"-"` + Name *string `gorm:"column:name;type:varchar(255);uniqueIndex:UniqueArtifactTypeName,priority:2" json:"-"` + ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_artifact_external_id,priority:1" json:"-"` + CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_artifact_create_time_since_epoch,priority:1" json:"-"` + LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_artifact_last_update_time_since_epoch,priority:1" json:"-"` + + // relationships + Properties []ArtifactProperty + ArtifactType Type `gorm:"foreignKey:TypeID;references:ID"` + Attributions []Attribution `gorm:"foreignKey:ArtifactID;references:ID"` + Events []Event +} + +// TableName Artifact's table name +func (*Artifact) TableName() string { + return TableNameArtifact +} + +type ArtifactState int + +const ( + UNKNOWN ArtifactState = iota + // PENDING A state indicating that the artifact may exist. + PENDING + // LIVE A state indicating that the artifact should exist, unless something + // external to the system deletes it. + LIVE + // MARKED_FOR_DELETION A state indicating that the artifact should be deleted. + MARKED_FOR_DELETION + // DELETED A state indicating that the artifact has been deleted. + DELETED + // ABANDONED A state indicating that the artifact has been abandoned, which may be + // due to a failed or cancelled execution. + ABANDONED + // REFERENCE A state indicating that the artifact is a reference artifact. At + // execution start time, the orchestrator produces an output artifact for + // each output key with state PENDING. However, for an intermediate + // artifact, this first artifact's state will be REFERENCE. Intermediate + // artifacts emitted during a component's execution will copy the REFERENCE + // artifact's attributes. At the end of an execution, the artifact state + // should remain REFERENCE instead of being changed to LIVE. + REFERENCE +) diff --git a/internal/model/db/artifactproperty.gen.go b/internal/model/db/artifactproperty.gen.go deleted file mode 100644 index cb615844..00000000 --- a/internal/model/db/artifactproperty.gen.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package db - -const TableNameArtifactProperty = "ArtifactProperty" - -// ArtifactProperty mapped from table -type ArtifactProperty struct { - ArtifactID int64 `gorm:"column:artifact_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey;index:idx_artifact_property_double,priority:1;index:idx_artifact_property_string,priority:1;index:idx_artifact_property_int,priority:1" json:"-"` - IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_artifact_property_double,priority:2;index:idx_artifact_property_string,priority:2;index:idx_artifact_property_int,priority:2" json:"-"` - IntValue *int64 `gorm:"column:int_value;index:idx_artifact_property_int,priority:3" json:"-"` - DoubleValue *float64 `gorm:"column:double_value;index:idx_artifact_property_double,priority:3" json:"-"` - StringValue *string `gorm:"column:string_value;index:idx_artifact_property_string,priority:3" json:"-"` - ByteValue *[]byte `gorm:"column:byte_value" json:"-"` - ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` - BoolValue *bool `gorm:"column:bool_value" json:"-"` -} - -// TableName ArtifactProperty's table name -func (*ArtifactProperty) TableName() string { - return TableNameArtifactProperty -} diff --git a/internal/model/db/artifactproperty.go b/internal/model/db/artifactproperty.go new file mode 100644 index 00000000..2a8aa1e8 --- /dev/null +++ b/internal/model/db/artifactproperty.go @@ -0,0 +1,102 @@ +package db + +const TableNameArtifactProperty = "ArtifactProperty" + +// ArtifactProperty mapped from table +type ArtifactProperty struct { + ArtifactID int64 `gorm:"column:artifact_id;primaryKey" json:"-"` + Name string `gorm:"column:name;primaryKey;index:idx_artifact_property_double,priority:1;index:idx_artifact_property_string,priority:1;index:idx_artifact_property_int,priority:1" json:"-"` + IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_artifact_property_double,priority:2;index:idx_artifact_property_string,priority:2;index:idx_artifact_property_int,priority:2" json:"-"` + IntValue *int64 `gorm:"column:int_value;index:idx_artifact_property_int,priority:3" json:"-"` + DoubleValue *float64 `gorm:"column:double_value;index:idx_artifact_property_double,priority:3" json:"-"` + StringValue *string `gorm:"column:string_value;index:idx_artifact_property_string,priority:3" json:"-"` + ByteValue *[]byte `gorm:"column:byte_value" json:"-"` + ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` + BoolValue *bool `gorm:"column:bool_value" json:"-"` + TypeURL *string `gorm:"column:type_url" json:"-"` +} + +// TableName ArtifactProperty's table name +func (*ArtifactProperty) TableName() string { + return TableNameArtifactProperty +} + +func (p *ArtifactProperty) GetID() int64 { + return p.ArtifactID +} + +func (p *ArtifactProperty) SetID(i int64) { + p.ArtifactID = i +} + +func (p *ArtifactProperty) GetName() string { + return p.Name +} + +func (p *ArtifactProperty) SetName(s string) { + p.Name = s +} + +func (p *ArtifactProperty) GetIsCustomProperty() bool { + return p.IsCustomProperty +} + +func (p *ArtifactProperty) SetIsCustomProperty(b bool) { + p.IsCustomProperty = b +} + +func (p *ArtifactProperty) GetIntValue() *int64 { + return p.IntValue +} + +func (p *ArtifactProperty) SetIntValue(i *int64) { + p.IntValue = i +} + +func (p *ArtifactProperty) GetDoubleValue() *float64 { + return p.DoubleValue +} + +func (p *ArtifactProperty) SetDoubleValue(f *float64) { + p.DoubleValue = f +} + +func (p *ArtifactProperty) GetStringValue() *string { + return p.StringValue +} + +func (p *ArtifactProperty) SetStringValue(s *string) { + p.StringValue = s +} + +func (p *ArtifactProperty) GetByteValue() *[]byte { + return p.ByteValue +} + +func (p *ArtifactProperty) SetByteValue(b *[]byte) { + p.ByteValue = b +} + +func (p *ArtifactProperty) GetProtoValue() *[]byte { + return p.ProtoValue +} + +func (p *ArtifactProperty) SetProtoValue(b *[]byte) { + p.ProtoValue = b +} + +func (p *ArtifactProperty) GetBoolValue() *bool { + return p.BoolValue +} + +func (p *ArtifactProperty) SetBoolValue(b *bool) { + p.BoolValue = b +} + +func (p *ArtifactProperty) GetTypeURL() *string { + return p.TypeURL +} + +func (p *ArtifactProperty) SetTypeURL(s *string) { + p.TypeURL = s +} diff --git a/internal/model/db/association.gen.go b/internal/model/db/association.go similarity index 80% rename from internal/model/db/association.gen.go rename to internal/model/db/association.go index cb108c82..662fcd8f 100644 --- a/internal/model/db/association.gen.go +++ b/internal/model/db/association.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameAssociation = "Association" diff --git a/internal/model/db/attribution.gen.go b/internal/model/db/attribution.go similarity index 80% rename from internal/model/db/attribution.gen.go rename to internal/model/db/attribution.go index f169e201..3de48eff 100644 --- a/internal/model/db/attribution.gen.go +++ b/internal/model/db/attribution.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameAttribution = "Attribution" diff --git a/internal/model/db/context.gen.go b/internal/model/db/context.go similarity index 81% rename from internal/model/db/context.gen.go rename to internal/model/db/context.go index a1bf7673..991b6e4b 100644 --- a/internal/model/db/context.gen.go +++ b/internal/model/db/context.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameContext = "Context" @@ -11,7 +7,7 @@ type Context struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueContextName,priority:1" json:"-"` Name string `gorm:"column:name;not null;uniqueIndex:UniqueContextName,priority:2" json:"-"` - ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_context_external_id,priority:1" json:"-"` + ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_context_external_id,priority:1" json:"-"` CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_context_create_time_since_epoch,priority:1" json:"-"` LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_context_last_update_time_since_epoch,priority:1" json:"-"` @@ -21,7 +17,7 @@ type Context struct { Attributions []Attribution `gorm:"foreignKey:ContextID;references:ID"` Associations []Association `gorm:"foreignKey:ContextID;references:ID"` - // self-reference for context graphs + // many to many self-reference for context graphs Parents []ParentContext `gorm:"foreignKey:ContextID;references:ID"` Children []ParentContext `gorm:"foreignKey:ParentContextID;references:ID"` } diff --git a/internal/model/db/contextproperty.gen.go b/internal/model/db/contextproperty.gen.go deleted file mode 100644 index 64cb841f..00000000 --- a/internal/model/db/contextproperty.gen.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package db - -const TableNameContextProperty = "ContextProperty" - -// ContextProperty mapped from table -type ContextProperty struct { - ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey;index:idx_context_property_int,priority:1;index:idx_context_property_string,priority:1;index:idx_context_property_double,priority:1" json:"-"` - IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_context_property_int,priority:2;index:idx_context_property_string,priority:2;index:idx_context_property_double,priority:2" json:"-"` - IntValue *int64 `gorm:"column:int_value;index:idx_context_property_int,priority:3" json:"-"` - DoubleValue *float64 `gorm:"column:double_value;index:idx_context_property_double,priority:3" json:"-"` - StringValue *string `gorm:"column:string_value;index:idx_context_property_string,priority:3" json:"-"` - ByteValue *[]byte `gorm:"column:byte_value" json:"-"` - ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` - BoolValue *bool `gorm:"column:bool_value" json:"-"` -} - -// TableName ContextProperty's table name -func (*ContextProperty) TableName() string { - return TableNameContextProperty -} diff --git a/internal/model/db/contextproperty.go b/internal/model/db/contextproperty.go new file mode 100644 index 00000000..0c6b1609 --- /dev/null +++ b/internal/model/db/contextproperty.go @@ -0,0 +1,102 @@ +package db + +const TableNameContextProperty = "ContextProperty" + +// ContextProperty mapped from table +type ContextProperty struct { + ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` + Name string `gorm:"column:name;primaryKey;index:idx_context_property_int,priority:1;index:idx_context_property_string,priority:1;index:idx_context_property_double,priority:1" json:"-"` + IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_context_property_int,priority:2;index:idx_context_property_string,priority:2;index:idx_context_property_double,priority:2" json:"-"` + IntValue *int64 `gorm:"column:int_value;index:idx_context_property_int,priority:3" json:"-"` + DoubleValue *float64 `gorm:"column:double_value;index:idx_context_property_double,priority:3" json:"-"` + StringValue *string `gorm:"column:string_value;index:idx_context_property_string,priority:3" json:"-"` + ByteValue *[]byte `gorm:"column:byte_value" json:"-"` + ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` + BoolValue *bool `gorm:"column:bool_value" json:"-"` + TypeURL *string `gorm:"column:type_url" json:"-"` +} + +// TableName ContextProperty's table name +func (*ContextProperty) TableName() string { + return TableNameContextProperty +} + +func (p *ContextProperty) GetID() int64 { + return p.ContextID +} + +func (p *ContextProperty) SetID(i int64) { + p.ContextID = i +} + +func (p *ContextProperty) GetName() string { + return p.Name +} + +func (p *ContextProperty) SetName(s string) { + p.Name = s +} + +func (p *ContextProperty) GetIsCustomProperty() bool { + return p.IsCustomProperty +} + +func (p *ContextProperty) SetIsCustomProperty(b bool) { + p.IsCustomProperty = b +} + +func (p *ContextProperty) GetIntValue() *int64 { + return p.IntValue +} + +func (p *ContextProperty) SetIntValue(i *int64) { + p.IntValue = i +} + +func (p *ContextProperty) GetDoubleValue() *float64 { + return p.DoubleValue +} + +func (p *ContextProperty) SetDoubleValue(f *float64) { + p.DoubleValue = f +} + +func (p *ContextProperty) GetStringValue() *string { + return p.StringValue +} + +func (p *ContextProperty) SetStringValue(s *string) { + p.StringValue = s +} + +func (p *ContextProperty) GetByteValue() *[]byte { + return p.ByteValue +} + +func (p *ContextProperty) SetByteValue(b *[]byte) { + p.ByteValue = b +} + +func (p *ContextProperty) GetProtoValue() *[]byte { + return p.ProtoValue +} + +func (p *ContextProperty) SetProtoValue(b *[]byte) { + p.ProtoValue = b +} + +func (p *ContextProperty) GetBoolValue() *bool { + return p.BoolValue +} + +func (p *ContextProperty) SetBoolValue(b *bool) { + p.BoolValue = b +} + +func (p *ContextProperty) GetTypeURL() *string { + return p.TypeURL +} + +func (p *ContextProperty) SetTypeURL(s *string) { + p.TypeURL = s +} diff --git a/internal/model/db/event.gen.go b/internal/model/db/event.gen.go deleted file mode 100644 index 8a113f33..00000000 --- a/internal/model/db/event.gen.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package db - -const TableNameEvent = "Event" - -// Event mapped from table -type Event struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueEvent,priority:1" json:"-"` - ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueEvent,priority:2;index:idx_event_execution_id,priority:1" json:"-"` - Type int64 `gorm:"column:type;not null;uniqueIndex:UniqueEvent,priority:3" json:"-"` - MillisecondsSinceEpoch *int64 `gorm:"autoCreateTime:milli;column:milliseconds_since_epoch;not null" json:"-"` - - // relationships - Artifact Artifact - Execution Execution -} - -// TableName Event's table name -func (*Event) TableName() string { - return TableNameEvent -} diff --git a/internal/model/db/event.go b/internal/model/db/event.go new file mode 100644 index 00000000..414607dd --- /dev/null +++ b/internal/model/db/event.go @@ -0,0 +1,39 @@ +package db + +const TableNameEvent = "Event" + +// Event mapped from table +type Event struct { + ID int64 `gorm:"column:id;not null;primaryKey;autoIncrement:true" json:"-"` + ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueEvent,priority:1" json:"-"` + ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueEvent,priority:2;index:idx_event_execution_id,priority:1" json:"-"` + Type int8 `gorm:"column:type;not null;uniqueIndex:UniqueEvent,priority:3" json:"-"` + MillisecondsSinceEpoch int64 `gorm:"autoCreateTime:milli;column:milliseconds_since_epoch;not null" json:"-"` + + // relationships + PathSteps []EventPath + Artifact Artifact + Execution Execution +} + +// TableName Event's table name +func (*Event) TableName() string { + return TableNameEvent +} + +type EventType int + +// Events distinguish between an artifact that is written by the execution +// (possibly as a cache), versus artifacts that are part of the declared +// output of the Execution. For more information on what DECLARED_ means, +// see the comment on the message. +const ( + EVENT_TYPE_UNKNOWN EventType = iota + DECLARED_OUTPUT + DECLARED_INPUT + INPUT + OUTPUT + INTERNAL_INPUT + INTERNAL_OUTPUT + PENDING_OUTPUT +) diff --git a/internal/model/db/eventpath.gen.go b/internal/model/db/eventpath.go similarity index 69% rename from internal/model/db/eventpath.gen.go rename to internal/model/db/eventpath.go index 1007865d..600b1002 100644 --- a/internal/model/db/eventpath.gen.go +++ b/internal/model/db/eventpath.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameEventPath = "EventPath" @@ -10,7 +6,7 @@ const TableNameEventPath = "EventPath" type EventPath struct { EventID int64 `gorm:"column:event_id;not null;index:idx_eventpath_event_id,priority:1" json:"-"` IsIndexStep bool `gorm:"column:is_index_step;not null" json:"-"` - StepIndex *int64 `gorm:"column:step_index" json:"-"` + StepIndex *int `gorm:"column:step_index" json:"-"` StepKey *string `gorm:"column:step_key" json:"-"` } diff --git a/internal/model/db/execution.gen.go b/internal/model/db/execution.go similarity index 68% rename from internal/model/db/execution.gen.go rename to internal/model/db/execution.go index f12c1bfe..fe067417 100644 --- a/internal/model/db/execution.gen.go +++ b/internal/model/db/execution.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameExecution = "Execution" @@ -10,9 +6,9 @@ const TableNameExecution = "Execution" type Execution struct { ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueExecutionTypeName,priority:1" json:"-"` - LastKnownState *int64 `gorm:"column:last_known_state" json:"-"` - Name *string `gorm:"column:name;uniqueIndex:UniqueExecutionTypeName,priority:2" json:"-"` - ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_execution_external_id,priority:1" json:"-"` + LastKnownState *int8 `gorm:"column:last_known_state" json:"-"` + Name *string `gorm:"column:name;type:varchar(255);uniqueIndex:UniqueExecutionTypeName,priority:2" json:"-"` + ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_execution_external_id,priority:1" json:"-"` CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_execution_create_time_since_epoch,priority:1" json:"-"` LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_execution_last_update_time_since_epoch,priority:1" json:"-"` @@ -27,3 +23,15 @@ type Execution struct { func (*Execution) TableName() string { return TableNameExecution } + +type ExecutionState int + +const ( + EXECUTION_STATE_UNKNOWN ExecutionState = iota + NEW + RUNNING + COMPLETE + FAILED + CACHED + CANCELED +) diff --git a/internal/model/db/executionproperty.gen.go b/internal/model/db/executionproperty.gen.go deleted file mode 100644 index 59735488..00000000 --- a/internal/model/db/executionproperty.gen.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package db - -const TableNameExecutionProperty = "ExecutionProperty" - -// ExecutionProperty mapped from table -type ExecutionProperty struct { - ExecutionID int64 `gorm:"column:execution_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey;index:idx_execution_property_string,priority:1;index:idx_execution_property_int,priority:1;index:idx_execution_property_double,priority:1" json:"-"` - IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_execution_property_string,priority:2;index:idx_execution_property_int,priority:2;index:idx_execution_property_double,priority:2" json:"-"` - IntValue *int64 `gorm:"column:int_value;index:idx_execution_property_int,priority:3" json:"-"` - DoubleValue *float64 `gorm:"column:double_value;index:idx_execution_property_double,priority:3" json:"-"` - StringValue *string `gorm:"column:string_value;index:idx_execution_property_string,priority:3" json:"-"` - ByteValue *[]byte `gorm:"column:byte_value" json:"-"` - ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` - BoolValue *bool `gorm:"column:bool_value" json:"-"` -} - -// TableName ExecutionProperty's table name -func (*ExecutionProperty) TableName() string { - return TableNameExecutionProperty -} diff --git a/internal/model/db/executionproperty.go b/internal/model/db/executionproperty.go new file mode 100644 index 00000000..e40619a3 --- /dev/null +++ b/internal/model/db/executionproperty.go @@ -0,0 +1,102 @@ +package db + +const TableNameExecutionProperty = "ExecutionProperty" + +// ExecutionProperty mapped from table +type ExecutionProperty struct { + ExecutionID int64 `gorm:"column:execution_id;primaryKey" json:"-"` + Name string `gorm:"column:name;primaryKey;index:idx_execution_property_string,priority:1;index:idx_execution_property_int,priority:1;index:idx_execution_property_double,priority:1" json:"-"` + IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_execution_property_string,priority:2;index:idx_execution_property_int,priority:2;index:idx_execution_property_double,priority:2" json:"-"` + IntValue *int64 `gorm:"column:int_value;index:idx_execution_property_int,priority:3" json:"-"` + DoubleValue *float64 `gorm:"column:double_value;index:idx_execution_property_double,priority:3" json:"-"` + StringValue *string `gorm:"column:string_value;index:idx_execution_property_string,priority:3" json:"-"` + ByteValue *[]byte `gorm:"column:byte_value" json:"-"` + ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` + BoolValue *bool `gorm:"column:bool_value" json:"-"` + TypeURL *string `gorm:"column:type_url" json:"-"` +} + +// TableName ExecutionProperty's table name +func (*ExecutionProperty) TableName() string { + return TableNameExecutionProperty +} + +func (p *ExecutionProperty) GetID() int64 { + return p.ExecutionID +} + +func (p *ExecutionProperty) SetID(i int64) { + p.ExecutionID = i +} + +func (p *ExecutionProperty) GetName() string { + return p.Name +} + +func (p *ExecutionProperty) SetName(s string) { + p.Name = s +} + +func (p *ExecutionProperty) GetIsCustomProperty() bool { + return p.IsCustomProperty +} + +func (p *ExecutionProperty) SetIsCustomProperty(b bool) { + p.IsCustomProperty = b +} + +func (p *ExecutionProperty) GetIntValue() *int64 { + return p.IntValue +} + +func (p *ExecutionProperty) SetIntValue(i *int64) { + p.IntValue = i +} + +func (p *ExecutionProperty) GetDoubleValue() *float64 { + return p.DoubleValue +} + +func (p *ExecutionProperty) SetDoubleValue(f *float64) { + p.DoubleValue = f +} + +func (p *ExecutionProperty) GetStringValue() *string { + return p.StringValue +} + +func (p *ExecutionProperty) SetStringValue(s *string) { + p.StringValue = s +} + +func (p *ExecutionProperty) GetByteValue() *[]byte { + return p.ByteValue +} + +func (p *ExecutionProperty) SetByteValue(b *[]byte) { + p.ByteValue = b +} + +func (p *ExecutionProperty) GetProtoValue() *[]byte { + return p.ProtoValue +} + +func (p *ExecutionProperty) SetProtoValue(b *[]byte) { + p.ProtoValue = b +} + +func (p *ExecutionProperty) GetBoolValue() *bool { + return p.BoolValue +} + +func (p *ExecutionProperty) SetBoolValue(b *bool) { + p.BoolValue = b +} + +func (p *ExecutionProperty) GetTypeURL() *string { + return p.TypeURL +} + +func (p *ExecutionProperty) SetTypeURL(s *string) { + p.TypeURL = s +} diff --git a/internal/model/db/mlmdenv.gen.go b/internal/model/db/mlmdenv.go similarity index 66% rename from internal/model/db/mlmdenv.gen.go rename to internal/model/db/mlmdenv.go index c12c60d1..e0b85cd3 100644 --- a/internal/model/db/mlmdenv.gen.go +++ b/internal/model/db/mlmdenv.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameMLMDEnv = "MLMDEnv" diff --git a/internal/model/db/parentcontext.gen.go b/internal/model/db/parentcontext.go similarity index 76% rename from internal/model/db/parentcontext.gen.go rename to internal/model/db/parentcontext.go index 8e9b2e9f..5b0c4824 100644 --- a/internal/model/db/parentcontext.gen.go +++ b/internal/model/db/parentcontext.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameParentContext = "ParentContext" diff --git a/internal/model/db/parenttype.gen.go b/internal/model/db/parenttype.go similarity index 72% rename from internal/model/db/parenttype.gen.go rename to internal/model/db/parenttype.go index f4863b9d..5fc0b364 100644 --- a/internal/model/db/parenttype.gen.go +++ b/internal/model/db/parenttype.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameParentType = "ParentType" diff --git a/internal/model/db/property_interface.go b/internal/model/db/property_interface.go new file mode 100644 index 00000000..18e512ac --- /dev/null +++ b/internal/model/db/property_interface.go @@ -0,0 +1,24 @@ +package db + +type MetadataProperty interface { + GetID() int64 + SetID(int64) + GetName() string + SetName(string) + GetIsCustomProperty() bool + SetIsCustomProperty(bool) + GetIntValue() *int64 + SetIntValue(*int64) + GetDoubleValue() *float64 + SetDoubleValue(*float64) + GetStringValue() *string + SetStringValue(*string) + GetByteValue() *[]byte + SetByteValue(*[]byte) + GetProtoValue() *[]byte + SetProtoValue(*[]byte) + GetBoolValue() *bool + SetBoolValue(*bool) + GetTypeURL() *string + SetTypeURL(*string) +} diff --git a/internal/model/db/type.gen.go b/internal/model/db/type.gen.go deleted file mode 100644 index 7b626e28..00000000 --- a/internal/model/db/type.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - -package db - -const TableNameType = "Type" - -// Type mapped from table -type Type struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - Name string `gorm:"column:name;not null;uniqueIndex:idx_type_name,priority:1" json:"-"` - Version *string `gorm:"column:version" json:"-"` - TypeKind int32 `gorm:"column:type_kind;not null" json:"-"` - Description *string `gorm:"column:description" json:"-"` - InputType *string `gorm:"column:input_type" json:"-"` - OutputType *string `gorm:"column:output_type" json:"-"` - ExternalID *string `gorm:"column:external_id;uniqueIndex:idx_type_external_id,priority:1" json:"-"` - - // relationships - Properties []TypeProperty -} - -// TableName Type's table name -func (*Type) TableName() string { - return TableNameType -} diff --git a/internal/model/db/type.go b/internal/model/db/type.go new file mode 100644 index 00000000..4b30d57a --- /dev/null +++ b/internal/model/db/type.go @@ -0,0 +1,32 @@ +package db + +const TableNameType = "Type" + +// Type mapped from table +type Type struct { + ID int64 `gorm:"column:id;not null;primaryKey;autoIncrement:true" json:"-"` + Name string `gorm:"column:name;type:varchar(255);not null;uniqueIndex:idx_type_name,priority:1" json:"-"` + Version *string `gorm:"column:version;type:varchar(255)" json:"-"` + TypeKind int8 `gorm:"column:type_kind;not null" json:"-"` + Description *string `gorm:"column:description;type:text" json:"-"` + InputType *string `gorm:"column:input_type;type:text" json:"-"` + OutputType *string `gorm:"column:output_type;type:text" json:"-"` + ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_type_external_id,priority:1" json:"-"` + + // relationships + Properties []TypeProperty +} + +// TableName Type's table name +func (*Type) TableName() string { + return TableNameType +} + +type TypeKind int + +// artifact type values from ml-metadata table values +const ( + EXECUTION_TYPE TypeKind = iota + ARTIFACT_TYPE + CONTEXT_TYPE +) diff --git a/internal/model/db/typeproperty.gen.go b/internal/model/db/typeproperty.go similarity index 75% rename from internal/model/db/typeproperty.gen.go rename to internal/model/db/typeproperty.go index c60ebbea..0e9c237c 100644 --- a/internal/model/db/typeproperty.gen.go +++ b/internal/model/db/typeproperty.go @@ -1,7 +1,3 @@ -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. -// Code generated by gorm.io/gen. DO NOT EDIT. - package db const TableNameTypeProperty = "TypeProperty" diff --git a/internal/server/grpc_server.go b/internal/server/grpc/grpc_server.go similarity index 94% rename from internal/server/grpc_server.go rename to internal/server/grpc/grpc_server.go index 00b401b2..c4d4fec3 100644 --- a/internal/server/grpc_server.go +++ b/internal/server/grpc/grpc_server.go @@ -1,4 +1,4 @@ -package server +package grpc import ( "context" @@ -6,32 +6,12 @@ import ( "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/db" + "github.com/opendatahub-io/model-registry/internal/server" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" ) -type TypeKind int32 - -// artifact type values from ml-metadata table values -const ( - EXECUTION_TYPE TypeKind = iota - ARTIFACT_TYPE - CONTEXT_TYPE -) - -func (tk TypeKind) String() string { - switch tk { - case EXECUTION_TYPE: - return "Execution" - case ARTIFACT_TYPE: - return "Artifact" - case CONTEXT_TYPE: - return "Context" - } - return "unknown" -} - type grpcServer struct { proto.UnimplementedMetadataStoreServiceServer dbConnection *gorm.DB @@ -47,7 +27,7 @@ func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { var REQUIRED_TYPE_FIELDS = []string{"name"} func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { - ctx, _ = Begin(ctx, g.dbConnection) + ctx, _ = server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) artifactType := request.GetArtifactType() @@ -59,7 +39,7 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif value := &db.Type{ Name: *artifactType.Name, Version: artifactType.Version, - TypeKind: int32(ARTIFACT_TYPE), + TypeKind: int8(db.ARTIFACT_TYPE), Description: artifactType.Description, ExternalID: artifactType.ExternalId, } @@ -76,7 +56,7 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, properties map[string]proto.PropertyType) error { // TODO handle CanAdd, CanOmit properties from type request - dbConn, _ := FromContext(ctx) + dbConn, _ := server.FromContext(ctx) if err := dbConn.Where("name = ?", value.Name).Assign(value).FirstOrCreate(value).Error; err != nil { err = fmt.Errorf("error creating type %s: %v", value.Name, err) @@ -90,7 +70,7 @@ func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, } func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { - ctx, _ = Begin(ctx, g.dbConnection) + ctx, _ = server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) executionType := request.GetExecutionType() @@ -101,7 +81,7 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec value := &db.Type{ Name: *executionType.Name, Version: executionType.Version, - TypeKind: int32(EXECUTION_TYPE), + TypeKind: int8(db.EXECUTION_TYPE), Description: executionType.Description, ExternalID: executionType.ExternalId, } @@ -116,7 +96,7 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec } func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { - ctx, _ = Begin(ctx, g.dbConnection) + ctx, _ = server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) contextType := request.GetContextType() @@ -127,7 +107,7 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex value := &db.Type{ Name: *contextType.Name, Version: contextType.Version, - TypeKind: int32(CONTEXT_TYPE), + TypeKind: int8(db.CONTEXT_TYPE), Description: contextType.Description, ExternalID: contextType.ExternalId, } @@ -142,7 +122,7 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex } func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest) (resp *proto.PutTypesResponse, err error) { - ctx, _ = Begin(ctx, g.dbConnection) + ctx, _ = server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) response := &proto.PutTypesResponse{} @@ -192,7 +172,7 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest var REQUIRED_ARTIFACT_FIELDS = []string{"type_id", "uri"} func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (resp *proto.PutArtifactsResponse, err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) + ctx, dbConn := server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) var artifactIds []int64 @@ -208,7 +188,10 @@ func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifact ExternalID: artifact.ExternalId, } nilSafeCopy(&value.ID, artifact.Id, identity[int64]) - nilSafeCopy(&value.State, artifact.State, artifactStateToInt64) + if artifact.State != nil { + state := int8(*artifact.State) + value.State = &state + } // create in DB if err = dbConn.Create(value).Error; err != nil { err = fmt.Errorf("error creating artifact with type_id[%d], name[%s]: %w", value.TypeID, *value.Name, err) @@ -267,14 +250,14 @@ func (g grpcServer) PutParentContexts(ctx context.Context, request *proto.PutPar } func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (resp *proto.GetArtifactTypeResponse, err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) + ctx, dbConn := server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) err = requiredFields(REQUIRED_TYPE_FIELDS, request.TypeName) response := &proto.GetArtifactTypeResponse{} var results []db.Type - rx := dbConn.Find(&results, db.Type{Name: *request.TypeName, TypeKind: int32(ARTIFACT_TYPE), Version: request.TypeVersion}) + rx := dbConn.Find(&results, db.Type{Name: *request.TypeName, TypeKind: int8(db.ARTIFACT_TYPE), Version: request.TypeVersion}) if rx.Error != nil { return nil, rx.Error } @@ -501,7 +484,7 @@ func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { } func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, typeId int64) (err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) + ctx, dbConn := server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { @@ -521,7 +504,7 @@ func (g grpcServer) createTypeProperties(ctx context.Context, properties map[str } func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto.Value, isCustomProperty bool) (err error) { - ctx, dbConn := Begin(ctx, g.dbConnection) + ctx, dbConn := server.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { @@ -571,10 +554,6 @@ func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int } func identity[T int64 | string](i T) T { return i } -func artifactStateToInt64(i proto.Artifact_State) *int64 { - var result = int64(i) - return &result -} func requiredFields(names []string, args ...interface{}) error { var missing []string @@ -597,14 +576,14 @@ func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto.Artifact_Sta func handleTransaction(ctx context.Context, err *error) { // handle panic if perr := recover(); perr != nil { - _ = Rollback(ctx) + _ = server.Rollback(ctx) *err = status.Errorf(codes.Internal, "server panic: %v", perr) return } if err == nil || *err == nil { - *err = Commit(ctx) + *err = server.Commit(ctx) } else { - _ = Rollback(ctx) + _ = server.Rollback(ctx) if _, ok := status.FromError(*err); !ok { *err = status.Errorf(codes.Internal, "internal error: %v", *err) } From f05b0aa3ae73d7b7a0998b55c579edc31240db24 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 27 Sep 2023 11:06:08 -0700 Subject: [PATCH 046/254] Fix failing assertion in python test --- test/python/test_mlmetadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/test_mlmetadata.py b/test/python/test_mlmetadata.py index d01bc3ba..057d1cf5 100644 --- a/test/python/test_mlmetadata.py +++ b/test/python/test_mlmetadata.py @@ -48,7 +48,7 @@ def main(): request = metadata_store_service_pb2.GetArtifactTypeRequest() request.type_name = "SavedModel" response = store.GetArtifactType(request) - assert response.artifact_type.id == 2 + assert response.artifact_type.id == model_type_id assert response.artifact_type.name == "SavedModel" # Query all registered Artifact types. From 2208ae0ea791147924f4ad48e5a50f041c3a9bb8 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 27 Sep 2023 14:51:40 -0700 Subject: [PATCH 047/254] Use protoc version v24.3 and add link in README.md --- .github/workflows/build.yml | 1 + README.md | 15 ++------------- internal/ml_metadata/proto/metadata_store.pb.go | 2 +- .../proto/metadata_store_service.pb.go | 2 +- .../proto/metadata_store_service_grpc.pb.go | 2 +- 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7f4040e0..67bc1914 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,6 +18,7 @@ jobs: - name: Install Protoc uses: arduino/setup-protoc@v2 with: + version: "24.3" repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Set up Python uses: actions/setup-python@v4 diff --git a/README.md b/README.md index 1fd8fa37..d6393bf7 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,7 @@ A go based server that implements a gRPC interface for [ml_metadata](https://git It adds other features on top of the functionality offered by the gRPC interface. ## Pre-requisites: - go >= 1.19 -- protoc - [Protocol buffer compiler](https://grpc.io/docs/protoc-installation/). -- go tools - Installed with the following commands: -``` -go install github.com/99designs/gqlgen@latest -curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.54.2 -go install github.com/searKing/golang/tools/go-enum@latest -``` -- gRPC go plugins - Installed with the following commands: -``` -go install google.golang.org/protobuf/cmd/protoc-gen-go@latest -go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest -``` +- protoc v24.3 - [Protocol Buffers v24.3 Release](https://github.com/protocolbuffers/protobuf/releases/tag/v24.3) - python 3.9 ## Building Run the following command to build the server binary: @@ -66,4 +55,4 @@ Where, 8080 is the default port that the server listens on. This port can be cha Run the following command to clean the DB file, generated gRPC and GraphQL models, etc.: ``` make clean -``` \ No newline at end of file +``` diff --git a/internal/ml_metadata/proto/metadata_store.pb.go b/internal/ml_metadata/proto/metadata_store.pb.go index 0d89cd2a..b616143b 100644 --- a/internal/ml_metadata/proto/metadata_store.pb.go +++ b/internal/ml_metadata/proto/metadata_store.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v3.20.3 +// protoc v4.24.3 // source: ml_metadata/proto/metadata_store.proto package proto diff --git a/internal/ml_metadata/proto/metadata_store_service.pb.go b/internal/ml_metadata/proto/metadata_store_service.pb.go index fadd1ce2..7a88900c 100644 --- a/internal/ml_metadata/proto/metadata_store_service.pb.go +++ b/internal/ml_metadata/proto/metadata_store_service.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.31.0 -// protoc v3.20.3 +// protoc v4.24.3 // source: ml_metadata/proto/metadata_store_service.proto package proto diff --git a/internal/ml_metadata/proto/metadata_store_service_grpc.pb.go b/internal/ml_metadata/proto/metadata_store_service_grpc.pb.go index cd3945f2..237d9a02 100644 --- a/internal/ml_metadata/proto/metadata_store_service_grpc.pb.go +++ b/internal/ml_metadata/proto/metadata_store_service_grpc.pb.go @@ -16,7 +16,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v3.20.3 +// - protoc v4.24.3 // source: ml_metadata/proto/metadata_store_service.proto package proto From e1e7f081562148ed9d970935786c4c4c9883eb5b Mon Sep 17 00:00:00 2001 From: tarilabs Date: Mon, 2 Oct 2023 08:59:36 +0200 Subject: [PATCH 048/254] Remove wrong copyright headers --- cmd/migrate.go | 15 --------------- cmd/root.go | 15 --------------- cmd/serve.go | 15 --------------- main.go | 15 --------------- 4 files changed, 60 deletions(-) diff --git a/cmd/migrate.go b/cmd/migrate.go index 85106f1e..4005d97d 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -1,18 +1,3 @@ -/* -Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com - -Licensed 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 cmd import ( diff --git a/cmd/root.go b/cmd/root.go index 80b714b4..f1966085 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,18 +1,3 @@ -/* -Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com - -Licensed 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 cmd import ( diff --git a/cmd/serve.go b/cmd/serve.go index bb5e0ee4..1379208a 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -1,18 +1,3 @@ -/* -Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com - -Licensed 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 cmd import ( diff --git a/main.go b/main.go index 75e605ab..693a0fc1 100644 --- a/main.go +++ b/main.go @@ -1,18 +1,3 @@ -/* -Copyright © 2023 Dhiraj Bokde dhirajsb@gmail.com - -Licensed 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 main import ( From d8277f5c62f046510a115e5434b4e8106bb6af29 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 27 Sep 2023 15:52:17 -0700 Subject: [PATCH 049/254] Add Dockerfile for registry, part of #15, fixes #40 --- Dockerfile | 46 +++++++++++++++++++++++++++++++++++++++++++++- Makefile | 2 +- README.md | 33 ++++++++++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index c24d5ef7..234dc71b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1 +1,45 @@ -FROM \ No newline at end of file +# Build the model-registry binary +FROM registry.access.redhat.com/ubi8/go-toolset:1.19 as builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY ["go.mod", "go.sum", "./"] +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +# Copy the go source +USER root +COPY ["Makefile", "main.go", "gqlgen.yml", "./"] + +# Download protoc compiler v24.3 +RUN wget -q https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-linux-x86_64.zip -O protoc.zip && \ + unzip -q protoc.zip && \ + bin/protoc --version && \ + rm protoc.zip + +# Download tools +RUN make deps + +# Copy rest of the source +COPY bin/ bin/ +COPY cmd/ cmd/ +COPY api/ api/ +COPY config/ config/ +COPY internal/ internal/ + +# Build +USER root +RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 make clean model-registry + +# Use distroless as minimal base image to package the model-registry binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 +WORKDIR / +# copy the metadata library +COPY --from=builder /workspace/config ./config +# copy the registry binary +COPY --from=builder /workspace/model-registry . +USER 65532:65532 + +ENTRYPOINT ["/model-registry"] diff --git a/Makefile b/Makefile index 90739775..f4bc1479 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ gen/grpc: internal/ml_metadata/proto/metadata_store.pb.go internal/ml_metadata/p gen/graph: internal/model/graph/models_gen.go internal/model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml - go run github.com/99designs/gqlgen generate + gqlgen generate .PHONY: vet vet: diff --git a/README.md b/README.md index d6393bf7..01efcef7 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ The generated binary uses spf13 cmdline args. More information on using the serv ``` ./model-registry --help ``` -## Creating/Migrating Server DB +## Server +### Creating/Migrating Server DB The server uses a local SQLite DB file (`metadata.sqlite.db` by default), which can be configured using the `-d` cmdline option. The following command creates the DB: ``` @@ -29,11 +30,12 @@ Note that currently no duplicate detection is done as the implementation is a WI Running this command multiple times will create duplicate metadata types. To clear the DB simply delete the SQLite DB file `metadata.sqlite.db`. -### Running Server +### Starting the Server Run the following command to start the server: ``` make run/server & ``` +## Clients ### Running Python ml-metadata test client Before running the test client, install the required Python libraries (using a python venv, if using one) using the command: @@ -52,7 +54,32 @@ http://localhost:8080/ ``` Where, 8080 is the default port that the server listens on. This port can be changed with the `-p` option. ### Clean -Run the following command to clean the DB file, generated gRPC and GraphQL models, etc.: +Run the following command to clean the server binary, generated gRPC and GraphQL models, etc.: ``` make clean ``` +## Docker Image +### Building the Docker Image +The following command builds a docker image for the server with the tag `model-registry``: +```shell +docker build -t model-registry . +``` +Note that the first build will be longer as it downloads the build tool dependencies. +Subsequent builds will re-use the cached tools layer. +### Creating/Migrating Server DB +The following command migrates or creates a DB for the server: +```shell +docker run -it --user : -v :/var/db model-registry migrate -d /var/db/metadata.sqlite.db -m /config/metadata-library +``` +Where, `` and `` are local user and group ids on the host machine to allow volume mapping for the DB files. +And, `` is the path on the local directory writable by the `:` user. +### Running the Server +The following command starts the server: +```shell +docker run -d -p ::8080 --user : -v :/var/db --name server model-registry serve -n 0.0.0.0 -d /var/db/metadata.sqlite.db +``` +Where, ``, ``, and `` are the same as in the migrate command above. +And `` and `` are the local ip and port to use to expose the container's default `8080` listening port. +The server listens on `localhost` by default, hence the `-n 0.0.0.0` option allows the server port to be exposed. + +Once the server has started, test clients and playground can be used as described in the above sections. From 57395c745e5565ac8787521f4ce7af0070af03f0 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Wed, 4 Oct 2023 14:04:15 +0200 Subject: [PATCH 050/254] Add first draft of Data Access Layer, with test (#34) * Add first draft of Data Access Layer, with test * implement code review feedback * move code into file structure as requested * Move DB fn into db_context.go * Reuse enum from db/type.go * Use :memory: sqlite as requested --------- Co-authored-by: Andrea Lamparelli --- internal/server/grpc/grpc_server.go | 26 ++-- internal/service/artifact_handler.go | 9 ++ internal/{server => service}/db_context.go | 22 +++- internal/service/db_service.go | 39 ++++++ internal/service/db_service_test.go | 146 +++++++++++++++++++++ internal/service/type_handler.go | 64 +++++++++ 6 files changed, 292 insertions(+), 14 deletions(-) create mode 100644 internal/service/artifact_handler.go rename internal/{server => service}/db_context.go (73%) create mode 100644 internal/service/db_service.go create mode 100644 internal/service/db_service_test.go create mode 100644 internal/service/type_handler.go diff --git a/internal/server/grpc/grpc_server.go b/internal/server/grpc/grpc_server.go index c4d4fec3..fbdf1db9 100644 --- a/internal/server/grpc/grpc_server.go +++ b/internal/server/grpc/grpc_server.go @@ -6,7 +6,7 @@ import ( "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/db" - "github.com/opendatahub-io/model-registry/internal/server" + "github.com/opendatahub-io/model-registry/internal/service" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "gorm.io/gorm" @@ -27,7 +27,7 @@ func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { var REQUIRED_TYPE_FIELDS = []string{"name"} func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { - ctx, _ = server.Begin(ctx, g.dbConnection) + ctx, _ = service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) artifactType := request.GetArtifactType() @@ -56,7 +56,7 @@ func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtif func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, properties map[string]proto.PropertyType) error { // TODO handle CanAdd, CanOmit properties from type request - dbConn, _ := server.FromContext(ctx) + dbConn, _ := service.FromContext(ctx) if err := dbConn.Where("name = ?", value.Name).Assign(value).FirstOrCreate(value).Error; err != nil { err = fmt.Errorf("error creating type %s: %v", value.Name, err) @@ -70,7 +70,7 @@ func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, } func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { - ctx, _ = server.Begin(ctx, g.dbConnection) + ctx, _ = service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) executionType := request.GetExecutionType() @@ -96,7 +96,7 @@ func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExec } func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { - ctx, _ = server.Begin(ctx, g.dbConnection) + ctx, _ = service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) contextType := request.GetContextType() @@ -122,7 +122,7 @@ func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContex } func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest) (resp *proto.PutTypesResponse, err error) { - ctx, _ = server.Begin(ctx, g.dbConnection) + ctx, _ = service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) response := &proto.PutTypesResponse{} @@ -172,7 +172,7 @@ func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest var REQUIRED_ARTIFACT_FIELDS = []string{"type_id", "uri"} func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (resp *proto.PutArtifactsResponse, err error) { - ctx, dbConn := server.Begin(ctx, g.dbConnection) + ctx, dbConn := service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) var artifactIds []int64 @@ -250,7 +250,7 @@ func (g grpcServer) PutParentContexts(ctx context.Context, request *proto.PutPar } func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (resp *proto.GetArtifactTypeResponse, err error) { - ctx, dbConn := server.Begin(ctx, g.dbConnection) + ctx, dbConn := service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) err = requiredFields(REQUIRED_TYPE_FIELDS, request.TypeName) @@ -484,7 +484,7 @@ func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { } func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, typeId int64) (err error) { - ctx, dbConn := server.Begin(ctx, g.dbConnection) + ctx, dbConn := service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { @@ -504,7 +504,7 @@ func (g grpcServer) createTypeProperties(ctx context.Context, properties map[str } func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto.Value, isCustomProperty bool) (err error) { - ctx, dbConn := server.Begin(ctx, g.dbConnection) + ctx, dbConn := service.Begin(ctx, g.dbConnection) defer handleTransaction(ctx, &err) for propName, prop := range properties { @@ -576,14 +576,14 @@ func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto.Artifact_Sta func handleTransaction(ctx context.Context, err *error) { // handle panic if perr := recover(); perr != nil { - _ = server.Rollback(ctx) + _ = service.Rollback(ctx) *err = status.Errorf(codes.Internal, "server panic: %v", perr) return } if err == nil || *err == nil { - *err = server.Commit(ctx) + *err = service.Commit(ctx) } else { - _ = server.Rollback(ctx) + _ = service.Rollback(ctx) if _, ok := status.FromError(*err); !ok { *err = status.Errorf(codes.Internal, "internal error: %v", *err) } diff --git a/internal/service/artifact_handler.go b/internal/service/artifact_handler.go new file mode 100644 index 00000000..290d5c11 --- /dev/null +++ b/internal/service/artifact_handler.go @@ -0,0 +1,9 @@ +package service + +import ( + "gorm.io/gorm" +) + +type artifactHandler struct { + db *gorm.DB +} diff --git a/internal/server/db_context.go b/internal/service/db_context.go similarity index 73% rename from internal/server/db_context.go rename to internal/service/db_context.go index a694df14..767f6dab 100644 --- a/internal/server/db_context.go +++ b/internal/service/db_context.go @@ -1,8 +1,11 @@ -package server +package service import ( "context" "fmt" + + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "gorm.io/gorm" ) @@ -63,3 +66,20 @@ func Rollback(ctx context.Context) error { // rollback in unwrapped parent context return nil } + +func handleTransaction(ctx context.Context, err *error) { + // handle panic + if perr := recover(); perr != nil { + _ = Rollback(ctx) + *err = status.Errorf(codes.Internal, "server panic: %v", perr) + return + } + if err == nil || *err == nil { + *err = Commit(ctx) + } else { + _ = Rollback(ctx) + if _, ok := status.FromError(*err); !ok { + *err = status.Errorf(codes.Internal, "internal error: %v", *err) + } + } +} diff --git a/internal/service/db_service.go b/internal/service/db_service.go new file mode 100644 index 00000000..28baa391 --- /dev/null +++ b/internal/service/db_service.go @@ -0,0 +1,39 @@ +package service + +import ( + "gorm.io/gorm" + + "github.com/opendatahub-io/model-registry/internal/model/db" +) + +var _ DBService = dbServiceHandler{} +var _ DBService = (*dbServiceHandler)(nil) + +func NewDBService(db *gorm.DB) DBService { + return &dbServiceHandler{ + typeHandler: &typeHandler{db: db}, + artifactHandler: &artifactHandler{db: db}, + } +} + +type DBService interface { + InsertType(db.Type) (*db.Type, error) + UpsertType(db.Type) (*db.Type, error) + ReadType(db.Type) (*db.Type, error) + // Get-like function to use a signature similar to the gorm `Where` func + ReadAllType(query interface{}, args ...interface{}) ([]*db.Type, error) + UpdateType(db.Type) (*db.Type, error) + DeleteType(db.Type) (*db.Type, error) + + // InsertEEE(db.EEE) (*db.EEE, error) + // UpsertEEE(db.EEE) (*db.EEE, error) + // ReadEEE(db.EEE) (*db.EEE, error) + // ReadAllEEE(query interface{}, args ...interface{}) ([]*db.EEE, error) + // UpdateEEE(db.EEE) (*db.EEE, error) + // DeleteEEE(db.EEE) (*db.EEE, error) +} + +type dbServiceHandler struct { + *typeHandler + *artifactHandler +} diff --git a/internal/service/db_service_test.go b/internal/service/db_service_test.go new file mode 100644 index 00000000..161b8fa0 --- /dev/null +++ b/internal/service/db_service_test.go @@ -0,0 +1,146 @@ +package service + +import ( + "fmt" + "testing" + + "github.com/opendatahub-io/model-registry/internal/model/db" + "gorm.io/driver/sqlite" + "gorm.io/gorm" +) + +func migrateDatabase(dbConn *gorm.DB) error { + // using only needed RDBMS type for the scope under test + err := dbConn.AutoMigrate( + db.Type{}, + db.TypeProperty{}, + // TODO: add as needed. + ) + if err != nil { + return fmt.Errorf("db migration failed: %w", err) + } + return nil +} + +func setup() (*gorm.DB, error) { + db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{}) + if err != nil { + return nil, err + } + err = migrateDatabase(db) + if err != nil { + return nil, err + } + return db, nil +} + +// Bare minimal test of PutArtifactType with a given Name, and Get. +func TestInsertTypeThenReadAllType(t *testing.T) { + dbc, err := setup() + if err != nil { + t.Errorf("Should expect DB connection: %v", err) + } + defer func() { + dbi, err := dbc.DB() + if err != nil { + t.Errorf("Test need to clear sqlite DB for the next one, but errored: %v", err) + } + dbi.Close() + }() + dal := NewDBService(dbc) + + artifactName := "John Doe" + newType := db.Type{ + Name: artifactName, + TypeKind: int8(db.ARTIFACT_TYPE), + } + + at, err := dal.InsertType(newType) + if err != nil { + t.Errorf("Should create ArtifactType: %v", err) + } + if at.ID < 0 { + t.Errorf("Should have ID for ArtifactType: %v", at.ID) + } + if at.Name != artifactName { + t.Errorf("Should have Name for ArtifactType per constant: %v", at.Name) + } + + ats, err2 := dal.ReadAllType(newType) + if err2 != nil { + t.Errorf("Should get ArtifactType: %v", err2) + } + if len(ats) != 1 { // TODO if temp file is okay, this is superfluos + t.Errorf("The test is running under different assumption") + } + at0 := ats[0] + t.Logf("at0: %v", at0) + if at0.ID != at.ID { + t.Errorf("Should have same ID") + } + if at0.Name != at.Name { + t.Errorf("Should have same Name") + } + +} + +func TestReadAllType(t *testing.T) { + dbc, err := setup() + if err != nil { + t.Errorf("Should expect DB connection: %v", err) + } + defer func() { + dbi, err := dbc.DB() + if err != nil { + t.Errorf("Test need to clear sqlite DB for the next one, but errored: %v", err) + } + dbi.Close() + }() + dal := NewDBService(dbc) + + fixVersion := "version" + + if _, err := dal.InsertType(db.Type{Name: "at0", Version: &fixVersion, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { + t.Errorf("Should create ArtifactType: %v", err) + } + if _, err := dal.InsertType(db.Type{Name: "at1", Version: &fixVersion, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { + t.Errorf("Should create ArtifactType: %v", err) + } + + results, err := dal.ReadAllType(db.Type{Version: &fixVersion}) + t.Logf("results: %v", results) + if err != nil { + t.Errorf("Should get ArtifactTypes: %v", err) + } + if len(results) != 2 { + t.Errorf("Should have retrieved 2 artifactTypes") + } +} + +func TestUpsertType(t *testing.T) { + dbc, err := setup() + if err != nil { + t.Errorf("Should expect DB connection: %v", err) + } + defer func() { + dbi, err := dbc.DB() + if err != nil { + t.Errorf("Test need to clear sqlite DB for the next one, but errored: %v", err) + } + dbi.Close() + }() + dal := NewDBService(dbc) + + artifactName := "John Doe" + v0 := "v0" + v1 := "v1" + if _, err := dal.InsertType(db.Type{Name: artifactName, Version: &v0, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { + t.Errorf("Should Insert ArtifactType: %v", err) + } + if res, err := dal.InsertType(db.Type{Name: artifactName, Version: &v0, TypeKind: int8(db.ARTIFACT_TYPE)}); err == nil { + t.Errorf("Subsequent Insert must have failed: %v", res) + } + if _, err := dal.UpsertType(db.Type{Name: artifactName, Version: &v1, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { + t.Errorf("Should Upsert ArtifactType: %v", err) + } +} diff --git a/internal/service/type_handler.go b/internal/service/type_handler.go new file mode 100644 index 00000000..44b92f63 --- /dev/null +++ b/internal/service/type_handler.go @@ -0,0 +1,64 @@ +package service + +import ( + "context" + "fmt" + + "github.com/opendatahub-io/model-registry/internal/model/db" + "gorm.io/gorm" +) + +type typeHandler struct { + db *gorm.DB +} + +func (h *typeHandler) InsertType(i db.Type) (r *db.Type, err error) { + ctx, _ := Begin(context.Background(), h.db) + defer handleTransaction(ctx, &err) + + result := h.db.Create(&i) + if result.Error != nil { + return nil, result.Error + } + return &i, nil +} + +func (h *typeHandler) UpsertType(i db.Type) (r *db.Type, err error) { + ctx, _ := Begin(context.Background(), h.db) + defer handleTransaction(ctx, &err) + + if err := h.db.Where("name = ?", i.Name).Assign(i).FirstOrCreate(&i).Error; err != nil { + err = fmt.Errorf("error creating type %s: %v", i.Name, err) + return nil, err + } + return &i, nil +} + +func (h *typeHandler) ReadType(i db.Type) (*db.Type, error) { + var results []*db.Type + rx := h.db.Find(&results) + if rx.Error != nil { + return nil, rx.Error + } + if len(results) > 1 { + return nil, fmt.Errorf("found more than one Type(s): %v", len(results)) + } + return results[0], nil +} + +func (h *typeHandler) ReadAllType(query interface{}, args ...interface{}) ([]*db.Type, error) { + var results []*db.Type + rx := h.db.Where(query, args).Find(&results) + if rx.Error != nil { + return nil, rx.Error + } + return results, nil +} + +func (h *typeHandler) UpdateType(i db.Type) (result *db.Type, err error) { + panic("unimplemented") +} + +func (h *typeHandler) DeleteType(i db.Type) (r *db.Type, err error) { + panic("unimplemented") +} From 421166711841eb9939e4affe3406ed4cd142a4b0 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Wed, 4 Oct 2023 18:51:58 +0200 Subject: [PATCH 051/254] Integrate MR GitHub issues into ODH dashboard (#54) * Integrate MR GitHub issues into ODH dashboard * Update .github/workflows/auto-add-issue-to-project.yml Co-authored-by: Andrea Lamparelli --------- Co-authored-by: Andrea Lamparelli --- .github/workflows/auto-add-issue-to-project.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/auto-add-issue-to-project.yml diff --git a/.github/workflows/auto-add-issue-to-project.yml b/.github/workflows/auto-add-issue-to-project.yml new file mode 100644 index 00000000..8b05131b --- /dev/null +++ b/.github/workflows/auto-add-issue-to-project.yml @@ -0,0 +1,14 @@ +name: Add Issues to Model Registry ODH board Project +on: + issues: + types: + - opened +jobs: + add-to-project: + name: Add issue to project + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@v0.5.0 + with: + project-url: https://github.com/orgs/opendatahub-io/projects/49 + github-token: ${{ secrets.GH_TOKEN }} From cabad696a136bbc56f65fd0a35bc87b8a652097c Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Sat, 30 Sep 2023 22:59:36 -0700 Subject: [PATCH 052/254] add support for reading config file using viper, fixes #12 --- cmd/config.go | 12 ++++++++++++ cmd/migrate.go | 12 +++++------- cmd/root.go | 44 ++++++++++++++++++++++++++++++++++++++------ cmd/serve.go | 16 ++++++---------- go.mod | 2 +- 5 files changed, 62 insertions(+), 24 deletions(-) create mode 100644 cmd/config.go diff --git a/cmd/config.go b/cmd/config.go new file mode 100644 index 00000000..0a7720a4 --- /dev/null +++ b/cmd/config.go @@ -0,0 +1,12 @@ +package cmd + +type Config struct { + DbFile string `mapstructure:"db-file" yaml:"db-file"` + Hostname string `mapstructure:"hostname" yaml:"hostname"` + Port int `mapstructure:"port" yaml:"port"` + LibraryDirs []string `mapstructure:"metadata-library-dir" yaml:"metadata-library-dir"` +} + +var cfg = Config{DbFile: "metadata.sqlite.db", Hostname: "localhost", Port: 8080, LibraryDirs: []string(nil)} + +const EnvPrefix = "MR" diff --git a/cmd/migrate.go b/cmd/migrate.go index 4005d97d..66b15cdd 100644 --- a/cmd/migrate.go +++ b/cmd/migrate.go @@ -23,7 +23,7 @@ This command can create a new ml-metadata Sqlite DB, or migrate an existing DB to the latest schema required by this server.`, RunE: func(cmd *cobra.Command, args []string) error { // connect to DB - dbConn, err := NewDatabaseConnection(dbFile) + dbConn, err := NewDatabaseConnection(cfg.DbFile) defer func() { // close DB connection on exit db, err2 := dbConn.DB() @@ -76,9 +76,9 @@ func migrateDatabase(dbConn *gorm.DB) error { } func loadLibraries(dbConn *gorm.DB) error { - libs, err := library.LoadLibraries(libraryDirs) + libs, err := library.LoadLibraries(cfg.LibraryDirs) if err != nil { - return fmt.Errorf("failed to read library directories %s: %w", libraryDirs, err) + return fmt.Errorf("failed to read library directories %s: %w", cfg.LibraryDirs, err) } for path, lib := range libs { grpcServer := grpc.NewGrpcServer(dbConn) @@ -128,8 +128,6 @@ func ToProtoProperties(props map[string]library.PropertyType) map[string]proto.P return result } -var libraryDirs []string - func init() { rootCmd.AddCommand(migrateCmd) @@ -141,6 +139,6 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: - migrateCmd.Flags().StringVarP(&dbFile, "db-file", "d", "metadata.sqlite.db", "Sqlite DB file") - migrateCmd.Flags().StringSliceVarP(&libraryDirs, "metadata-library-dir", "m", libraryDirs, "Built-in metadata types library directories containing yaml files") + migrateCmd.Flags().StringVarP(&cfg.DbFile, "db-file", "d", cfg.DbFile, "Sqlite DB file") + migrateCmd.Flags().StringSliceVarP(&cfg.LibraryDirs, "metadata-library-dir", "m", cfg.LibraryDirs, "Built-in metadata types library directories containing yaml files") } diff --git a/cmd/root.go b/cmd/root.go index f1966085..31ca6ddf 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,10 +1,13 @@ package cmd import ( + "errors" "flag" "fmt" "github.com/golang/glog" + "github.com/spf13/pflag" "os" + "strings" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -28,6 +31,9 @@ custom metadata libraries, exposing a higher level GraphQL API, RBAC, etc.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + return initConfig(cmd) + }, } // Execute adds all child commands to the root command and sets flags appropriately. @@ -40,13 +46,13 @@ func Execute() { } func init() { - cobra.OnInitialize(initConfig) + //cobra.OnInitialize(initConfig) // Here you will define your flags and configuration settings. // Cobra supports persistent flags, which, if defined here, // will be global for your application. - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.model-registry.yaml)") + rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.model-registry.yaml)") // default to logging to stderr _ = flag.Set("logtostderr", "true") @@ -55,19 +61,21 @@ func init() { // Cobra also supports local flags, which will only run // when this action is called directly. - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + //rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } // initConfig reads in config file and ENV variables if set. -func initConfig() { +func initConfig(cmd *cobra.Command) error { if cfgFile != "" { // Use config file from the flag. viper.SetConfigFile(cfgFile) } else { // Find home directory. home, err := os.UserHomeDir() - cobra.CheckErr(err) + if err != nil { + return err + } // Search config in home directory with name ".model-registry" (without extension). viper.AddConfigPath(home) @@ -75,10 +83,34 @@ func initConfig() { viper.SetConfigName(".model-registry") } + viper.SetEnvPrefix(EnvPrefix) + viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_")) viper.AutomaticEnv() // read in environment variables that match // If a config file is found, read it in. if err := viper.ReadInConfig(); err == nil { - fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + glog.Info("using config file: ", viper.ConfigFileUsed()) + } else { + var configFileNotFoundError viper.ConfigFileNotFoundError + ok := errors.As(err, &configFileNotFoundError) + // ignore if it's a file not found error for default config file + if !(cfgFile == "" && ok) { + return fmt.Errorf("reading config %s: %v", viper.ConfigFileUsed(), err) + } + } + + // bind flags to config + if err := viper.BindPFlags(cmd.Flags()); err != nil { + return err } + var err error + cmd.Flags().VisitAll(func(f *pflag.Flag) { + name := f.Name + if err == nil && !f.Changed && viper.IsSet(name) { + value := viper.Get(name) + err = cmd.Flags().Set(name, fmt.Sprintf("%v", value)) + } + }) + + return err } diff --git a/cmd/serve.go b/cmd/serve.go index 1379208a..a494079f 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -47,10 +47,6 @@ func InterceptorLogger(l *log.Logger) logging.Logger { } var ( - dbFile string - host = "localhost" - port int = 8080 - // serveCmd represents the serve command serveCmd = &cobra.Command{ Use: "serve", @@ -64,7 +60,7 @@ location of the database file and the hostname and port where it listens.'`, ) func runServer(cmd *cobra.Command, args []string) error { - glog.Info("server started...") + glog.Infof("server started at %s:%v", cfg.Hostname, cfg.Port) // Create a channel to receive signals signalChannel := make(chan os.Signal, 1) @@ -73,13 +69,13 @@ func runServer(cmd *cobra.Command, args []string) error { signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) // connect to the DB using Gorm - db, err := NewDatabaseConnection(dbFile) + db, err := NewDatabaseConnection(cfg.DbFile) if err != nil { log.Fatalf("db connection failed: %v", err) } // listen on host:port - listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port)) + listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.Hostname, cfg.Port)) if err != nil { log.Fatalf("server listen failed: %v", err) } @@ -189,7 +185,7 @@ func init() { // Cobra supports local flags which will only run when this command // is called directly, e.g.: - serveCmd.Flags().StringVarP(&dbFile, "db-file", "d", "metadata.sqlite.db", "Sqlite DB file") - serveCmd.Flags().StringVarP(&host, "hostname", "n", host, "Server listen hostname") - serveCmd.Flags().IntVarP(&port, "port", "p", port, "Server listen port") + serveCmd.Flags().StringVarP(&cfg.DbFile, "db-file", "d", cfg.DbFile, "Sqlite DB file") + serveCmd.Flags().StringVarP(&cfg.Hostname, "hostname", "n", cfg.Hostname, "Server listen hostname") + serveCmd.Flags().IntVarP(&cfg.Port, "port", "p", cfg.Port, "Server listen port") } diff --git a/go.mod b/go.mod index bdbec28a..9a1bfbc8 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/searKing/golang/tools/go-enum v1.2.97 github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.7.0 + github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 github.com/vektah/gqlparser/v2 v2.5.8 golang.org/x/sync v0.2.0 @@ -41,7 +42,6 @@ require ( github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.4.2 // indirect github.com/urfave/cli/v2 v2.25.5 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect From 6644876aee08bfaa70120b09e3fb0fa757681d05 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Wed, 4 Oct 2023 22:52:08 +0200 Subject: [PATCH 053/254] Update GHA to use github-app token (#56) --- .github/workflows/auto-add-issue-to-project.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/auto-add-issue-to-project.yml b/.github/workflows/auto-add-issue-to-project.yml index 8b05131b..aa5aac36 100644 --- a/.github/workflows/auto-add-issue-to-project.yml +++ b/.github/workflows/auto-add-issue-to-project.yml @@ -8,7 +8,13 @@ jobs: name: Add issue to project runs-on: ubuntu-latest steps: + - name: Generate github-app token + id: app-token + uses: getsentry/action-github-app-token@v2 + with: + app_id: ${{ secrets.DEVOPS_APP_ID }} + private_key: ${{ secrets.DEVOPS_APP_PRIVATE_KEY }} - uses: actions/add-to-project@v0.5.0 with: project-url: https://github.com/orgs/opendatahub-io/projects/49 - github-token: ${{ secrets.GH_TOKEN }} + github-token: ${{ steps.app-token.outputs.token }} From ab5d90ac9457731ac0491a7ec4240d528ff6cca6 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 19 Sep 2023 17:31:01 -0700 Subject: [PATCH 054/254] Fix makefile dep target to only download missing tools in bin/* --- Makefile | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index f4bc1479..6af6b90d 100644 --- a/Makefile +++ b/Makefile @@ -28,14 +28,27 @@ vet: clean: rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go -.PHONY: deps -deps: - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.54.2 - GOBIN=$(PROJECT_BIN) go install github.com/99designs/gqlgen@v0.17.36 +bin/go-enum: GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 + +bin/protoc-gen-go: GOBIN=$(PROJECT_BIN) go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.31.0 + +bin/protoc-gen-go-grpc: GOBIN=$(PROJECT_BIN) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 +bin/gqlgen: + GOBIN=$(PROJECT_BIN) go install github.com/99designs/gqlgen@v0.17.36 + +bin/golangci-lint: + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.54.2 + +bin/goverter: + GOBIN=$(PROJECT_PATH)/bin go install github.com/jmattheis/goverter/cmd/goverter@v0.18.0 + +.PHONY: deps +deps: bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/gqlgen bin/golangci-lint bin/goverter + .PHONY: vendor vendor: go mod vendor From e3df56972ede689e148a4482302c191a29052b25 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 26 Sep 2023 18:42:58 -0700 Subject: [PATCH 055/254] Fixes #37, add pprof support --- main.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/main.go b/main.go index 693a0fc1..bccdb30f 100644 --- a/main.go +++ b/main.go @@ -3,10 +3,18 @@ package main import ( "github.com/golang/glog" "github.com/opendatahub-io/model-registry/cmd" + "log" + "net/http" + _ "net/http/pprof" ) func main() { defer glog.Flush() + // start pprof server on 6060 + go func() { + log.Println(http.ListenAndServe("localhost:6060", nil)) + }() + cmd.Execute() } From 2aa1893dc50c41ef9124c14b8caad03635acc3ee Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 26 Sep 2023 18:36:23 -0700 Subject: [PATCH 056/254] Fixes #11, add gRPC to/from DB type converter --- Makefile | 10 +- internal/converter/generated/converter.go | 409 ++++++++++++++++++++++ internal/converter/grpc_converter.go | 80 +++++ internal/converter/grpc_converter_util.go | 355 +++++++++++++++++++ 4 files changed, 852 insertions(+), 2 deletions(-) create mode 100755 internal/converter/generated/converter.go create mode 100644 internal/converter/grpc_converter.go create mode 100644 internal/converter/grpc_converter_util.go diff --git a/Makefile b/Makefile index 6af6b90d..e285d637 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,12 @@ internal/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto .PHONY: gen/grpc gen/grpc: internal/ml_metadata/proto/metadata_store.pb.go internal/ml_metadata/proto/metadata_store_service.pb.go +internal/converter/generated/converter.go: internal/converter/*.go + goverter -packageName generated -output ./internal/converter/generated/converter.go github.com/opendatahub-io/model-registry/internal/converter/ + +.PHONY: gen/converter +gen/converter: gen/grpc gen/graph internal/converter/generated/converter.go + .PHONY: gen/graph gen/graph: internal/model/graph/models_gen.go @@ -26,7 +32,7 @@ vet: .PHONY: clean clean: - rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go + rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/converter.go bin/go-enum: GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 @@ -58,7 +64,7 @@ build: gen vet lint go build .PHONY: gen -gen: gen/grpc gen/graph +gen: deps gen/grpc gen/graph gen/converter go generate ./... .PHONY: lint diff --git a/internal/converter/generated/converter.go b/internal/converter/generated/converter.go new file mode 100755 index 00000000..69f285ac --- /dev/null +++ b/internal/converter/generated/converter.go @@ -0,0 +1,409 @@ +// Code generated by github.com/jmattheis/goverter, DO NOT EDIT. + +package generated + +import ( + "fmt" + converter "github.com/opendatahub-io/model-registry/internal/converter" + proto "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + db "github.com/opendatahub-io/model-registry/internal/model/db" +) + +type GRPCConverterImpl struct{} + +func (c *GRPCConverterImpl) ConvertArtifact(source *proto.Artifact) (*db.Artifact, error) { + var pDbArtifact *db.Artifact + if source != nil { + var dbArtifact db.Artifact + var xint64 int64 + if (*source).Id != nil { + xint64 = *(*source).Id + } + dbArtifact.ID = xint64 + var xint642 int64 + if (*source).TypeId != nil { + xint642 = *(*source).TypeId + } + dbArtifact.TypeID = xint642 + var pString *string + if (*source).Uri != nil { + xstring := *(*source).Uri + pString = &xstring + } + dbArtifact.URI = pString + dbArtifact.State = converter.ConvertArtifact_State((*source).State) + var pString2 *string + if (*source).Name != nil { + xstring2 := *(*source).Name + pString2 = &xstring2 + } + dbArtifact.Name = pString2 + var pString3 *string + if (*source).ExternalId != nil { + xstring3 := *(*source).ExternalId + pString3 = &xstring3 + } + dbArtifact.ExternalID = pString3 + var xint643 int64 + if (*source).CreateTimeSinceEpoch != nil { + xint643 = *(*source).CreateTimeSinceEpoch + } + dbArtifact.CreateTimeSinceEpoch = xint643 + var xint644 int64 + if (*source).LastUpdateTimeSinceEpoch != nil { + xint644 = *(*source).LastUpdateTimeSinceEpoch + } + dbArtifact.LastUpdateTimeSinceEpoch = xint644 + dbArtifactPropertyList, err := converter.ConvertProtoArtifactProperties(source) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + dbArtifact.Properties = dbArtifactPropertyList + pDbArtifact = &dbArtifact + } + return pDbArtifact, nil +} +func (c *GRPCConverterImpl) ConvertAssociation(source *proto.Association) (*db.Association, error) { + var pDbAssociation *db.Association + if source != nil { + var dbAssociation db.Association + var xint64 int64 + if (*source).ContextId != nil { + xint64 = *(*source).ContextId + } + dbAssociation.ContextID = xint64 + var xint642 int64 + if (*source).ExecutionId != nil { + xint642 = *(*source).ExecutionId + } + dbAssociation.ExecutionID = xint642 + pDbAssociation = &dbAssociation + } + return pDbAssociation, nil +} +func (c *GRPCConverterImpl) ConvertAttribution(source *proto.Attribution) (*db.Attribution, error) { + var pDbAttribution *db.Attribution + if source != nil { + var dbAttribution db.Attribution + var xint64 int64 + if (*source).ContextId != nil { + xint64 = *(*source).ContextId + } + dbAttribution.ContextID = xint64 + var xint642 int64 + if (*source).ArtifactId != nil { + xint642 = *(*source).ArtifactId + } + dbAttribution.ArtifactID = xint642 + pDbAttribution = &dbAttribution + } + return pDbAttribution, nil +} +func (c *GRPCConverterImpl) ConvertContext(source *proto.Context) (*db.Context, error) { + var pDbContext *db.Context + if source != nil { + var dbContext db.Context + var xint64 int64 + if (*source).Id != nil { + xint64 = *(*source).Id + } + dbContext.ID = xint64 + var xint642 int64 + if (*source).TypeId != nil { + xint642 = *(*source).TypeId + } + dbContext.TypeID = xint642 + var xstring string + if (*source).Name != nil { + xstring = *(*source).Name + } + dbContext.Name = xstring + var pString *string + if (*source).ExternalId != nil { + xstring2 := *(*source).ExternalId + pString = &xstring2 + } + dbContext.ExternalID = pString + var xint643 int64 + if (*source).CreateTimeSinceEpoch != nil { + xint643 = *(*source).CreateTimeSinceEpoch + } + dbContext.CreateTimeSinceEpoch = xint643 + var xint644 int64 + if (*source).LastUpdateTimeSinceEpoch != nil { + xint644 = *(*source).LastUpdateTimeSinceEpoch + } + dbContext.LastUpdateTimeSinceEpoch = xint644 + dbContextPropertyList, err := converter.ConvertProtoContextProperties(source) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + dbContext.Properties = dbContextPropertyList + pDbContext = &dbContext + } + return pDbContext, nil +} +func (c *GRPCConverterImpl) ConvertEvent(source *proto.Event) (*db.Event, error) { + var pDbEvent *db.Event + if source != nil { + var dbEvent db.Event + var xint64 int64 + if (*source).ArtifactId != nil { + xint64 = *(*source).ArtifactId + } + dbEvent.ArtifactID = xint64 + var xint642 int64 + if (*source).ExecutionId != nil { + xint642 = *(*source).ExecutionId + } + dbEvent.ExecutionID = xint642 + dbEvent.Type = converter.ConvertProtoEventType((*source).Type) + var xint643 int64 + if (*source).MillisecondsSinceEpoch != nil { + xint643 = *(*source).MillisecondsSinceEpoch + } + dbEvent.MillisecondsSinceEpoch = xint643 + dbEventPathList, err := converter.ConvertProtoEventPath((*source).Path) + if err != nil { + return nil, fmt.Errorf("error setting field PathSteps: %w", err) + } + dbEvent.PathSteps = dbEventPathList + pDbEvent = &dbEvent + } + return pDbEvent, nil +} +func (c *GRPCConverterImpl) ConvertExecution(source *proto.Execution) (*db.Execution, error) { + var pDbExecution *db.Execution + if source != nil { + var dbExecution db.Execution + var xint64 int64 + if (*source).Id != nil { + xint64 = *(*source).Id + } + dbExecution.ID = xint64 + var xint642 int64 + if (*source).TypeId != nil { + xint642 = *(*source).TypeId + } + dbExecution.TypeID = xint642 + dbExecution.LastKnownState = converter.ConvertExecution_State((*source).LastKnownState) + var pString *string + if (*source).Name != nil { + xstring := *(*source).Name + pString = &xstring + } + dbExecution.Name = pString + var pString2 *string + if (*source).ExternalId != nil { + xstring2 := *(*source).ExternalId + pString2 = &xstring2 + } + dbExecution.ExternalID = pString2 + var xint643 int64 + if (*source).CreateTimeSinceEpoch != nil { + xint643 = *(*source).CreateTimeSinceEpoch + } + dbExecution.CreateTimeSinceEpoch = xint643 + var xint644 int64 + if (*source).LastUpdateTimeSinceEpoch != nil { + xint644 = *(*source).LastUpdateTimeSinceEpoch + } + dbExecution.LastUpdateTimeSinceEpoch = xint644 + dbExecutionPropertyList, err := converter.ConvertProtoExecutionProperties(source) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + dbExecution.Properties = dbExecutionPropertyList + pDbExecution = &dbExecution + } + return pDbExecution, nil +} +func (c *GRPCConverterImpl) ConvertToArtifact(source *db.Artifact) (*proto.Artifact, error) { + var pProtoArtifact *proto.Artifact + if source != nil { + var protoArtifact proto.Artifact + pInt64 := (*source).ID + protoArtifact.Id = &pInt64 + var pString *string + if (*source).Name != nil { + xstring := *(*source).Name + pString = &xstring + } + protoArtifact.Name = pString + pInt642 := (*source).TypeID + protoArtifact.TypeId = &pInt642 + pString2, err := converter.ConvertTypeIDToName((*source).ID) + if err != nil { + return nil, fmt.Errorf("error setting field Type: %w", err) + } + protoArtifact.Type = pString2 + var pString3 *string + if (*source).URI != nil { + xstring2 := *(*source).URI + pString3 = &xstring2 + } + protoArtifact.Uri = pString3 + var pString4 *string + if (*source).ExternalID != nil { + xstring3 := *(*source).ExternalID + pString4 = &xstring3 + } + protoArtifact.ExternalId = pString4 + mapStringPProtoValue, err := converter.ConvertToProtoArtifactProperties((*source).Properties) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoArtifact.Properties = mapStringPProtoValue + mapStringPProtoValue2, err := converter.ConvertToProtoArtifactCustomProperties((*source).Properties) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoArtifact.CustomProperties = mapStringPProtoValue2 + pProtoArtifact_State, err := converter.ConvertToArtifact_State((*source).State) + if err != nil { + return nil, fmt.Errorf("error setting field State: %w", err) + } + protoArtifact.State = pProtoArtifact_State + pInt643 := (*source).CreateTimeSinceEpoch + protoArtifact.CreateTimeSinceEpoch = &pInt643 + pInt644 := (*source).LastUpdateTimeSinceEpoch + protoArtifact.LastUpdateTimeSinceEpoch = &pInt644 + pProtoArtifact = &protoArtifact + } + return pProtoArtifact, nil +} +func (c *GRPCConverterImpl) ConvertToAssociation(source *db.Association) (*proto.Association, error) { + var pProtoAssociation *proto.Association + if source != nil { + var protoAssociation proto.Association + pInt64 := (*source).ExecutionID + protoAssociation.ExecutionId = &pInt64 + pInt642 := (*source).ContextID + protoAssociation.ContextId = &pInt642 + pProtoAssociation = &protoAssociation + } + return pProtoAssociation, nil +} +func (c *GRPCConverterImpl) ConvertToAttribution(source *db.Attribution) (*proto.Attribution, error) { + var pProtoAttribution *proto.Attribution + if source != nil { + var protoAttribution proto.Attribution + pInt64 := (*source).ArtifactID + protoAttribution.ArtifactId = &pInt64 + pInt642 := (*source).ContextID + protoAttribution.ContextId = &pInt642 + pProtoAttribution = &protoAttribution + } + return pProtoAttribution, nil +} +func (c *GRPCConverterImpl) ConvertToContext(source *db.Context) (*proto.Context, error) { + var pProtoContext *proto.Context + if source != nil { + var protoContext proto.Context + pInt64 := (*source).ID + protoContext.Id = &pInt64 + pString := (*source).Name + protoContext.Name = &pString + pInt642 := (*source).TypeID + protoContext.TypeId = &pInt642 + pString2, err := converter.ConvertTypeIDToName((*source).ID) + if err != nil { + return nil, fmt.Errorf("error setting field Type: %w", err) + } + protoContext.Type = pString2 + var pString3 *string + if (*source).ExternalID != nil { + xstring := *(*source).ExternalID + pString3 = &xstring + } + protoContext.ExternalId = pString3 + mapStringPProtoValue, err := converter.ConvertToProtoContextProperties((*source).Properties) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoContext.Properties = mapStringPProtoValue + mapStringPProtoValue2, err := converter.ConvertToProtoContextCustomProperties((*source).Properties) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoContext.CustomProperties = mapStringPProtoValue2 + pInt643 := (*source).CreateTimeSinceEpoch + protoContext.CreateTimeSinceEpoch = &pInt643 + pInt644 := (*source).LastUpdateTimeSinceEpoch + protoContext.LastUpdateTimeSinceEpoch = &pInt644 + pProtoContext = &protoContext + } + return pProtoContext, nil +} +func (c *GRPCConverterImpl) ConvertToEvent(source *db.Event) (*proto.Event, error) { + var pProtoEvent *proto.Event + if source != nil { + var protoEvent proto.Event + pInt64 := (*source).ArtifactID + protoEvent.ArtifactId = &pInt64 + pInt642 := (*source).ExecutionID + protoEvent.ExecutionId = &pInt642 + pProtoEvent_Path, err := converter.ConvertToProtoEventPath((*source).PathSteps) + if err != nil { + return nil, fmt.Errorf("error setting field Path: %w", err) + } + protoEvent.Path = pProtoEvent_Path + pProtoEvent_Type, err := converter.ConvertToProtoEventType((*source).Type) + if err != nil { + return nil, fmt.Errorf("error setting field Type: %w", err) + } + protoEvent.Type = pProtoEvent_Type + pInt643 := (*source).MillisecondsSinceEpoch + protoEvent.MillisecondsSinceEpoch = &pInt643 + pProtoEvent = &protoEvent + } + return pProtoEvent, nil +} +func (c *GRPCConverterImpl) ConvertToExecution(source *db.Execution) (*proto.Execution, error) { + var pProtoExecution *proto.Execution + if source != nil { + var protoExecution proto.Execution + pInt64 := (*source).ID + protoExecution.Id = &pInt64 + var pString *string + if (*source).Name != nil { + xstring := *(*source).Name + pString = &xstring + } + protoExecution.Name = pString + pInt642 := (*source).TypeID + protoExecution.TypeId = &pInt642 + pString2, err := converter.ConvertTypeIDToName((*source).ID) + if err != nil { + return nil, fmt.Errorf("error setting field Type: %w", err) + } + protoExecution.Type = pString2 + var pString3 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString3 = &xstring2 + } + protoExecution.ExternalId = pString3 + pProtoExecution_State, err := converter.ConvertToExecution_State((*source).LastKnownState) + if err != nil { + return nil, fmt.Errorf("error setting field LastKnownState: %w", err) + } + protoExecution.LastKnownState = pProtoExecution_State + mapStringPProtoValue, err := converter.ConvertToProtoExecutionProperties((*source).Properties) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoExecution.Properties = mapStringPProtoValue + mapStringPProtoValue2, err := converter.ConvertToProtoExecutionCustomProperties((*source).Properties) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoExecution.CustomProperties = mapStringPProtoValue2 + pInt643 := (*source).CreateTimeSinceEpoch + protoExecution.CreateTimeSinceEpoch = &pInt643 + pInt644 := (*source).LastUpdateTimeSinceEpoch + protoExecution.LastUpdateTimeSinceEpoch = &pInt644 + pProtoExecution = &protoExecution + } + return pProtoExecution, nil +} diff --git a/internal/converter/grpc_converter.go b/internal/converter/grpc_converter.go new file mode 100644 index 00000000..56d85d37 --- /dev/null +++ b/internal/converter/grpc_converter.go @@ -0,0 +1,80 @@ +package converter + +import ( + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/db" + "gorm.io/gorm" +) + +var ( + // singleton DB connection for type name lookup + globalDB *gorm.DB +) + +// SetConverterDB must be called before using gRPC converters, +// it uses the singleton DB connection to lookup type names +func SetConverterDB(db *gorm.DB) { + if globalDB != nil { + panic("converter global DB connection MUST only be set once") + } + globalDB = db +} + +// goverter:converter +// goverter:wrapErrors +// goverter:matchIgnoreCase +// goverter:useZeroValueOnPointerInconsistency +type GRPCConverter interface { + // goverter:map State | ConvertArtifact_State + // goverter:map . Properties | ConvertProtoArtifactProperties + // goverter:ignore ArtifactType Attributions Events + ConvertArtifact(source *proto.Artifact) (*db.Artifact, error) + // goverter:map State | ConvertToArtifact_State + // goverter:map ID Id + // goverter:map ID Type | ConvertTypeIDToName + // goverter:map Properties Properties | ConvertToProtoArtifactProperties + // goverter:map Properties CustomProperties | ConvertToProtoArtifactCustomProperties + // goverter:ignore state sizeCache unknownFields SystemMetadata + ConvertToArtifact(source *db.Artifact) (*proto.Artifact, error) + + // goverter:map . Properties | ConvertProtoContextProperties + // goverter:ignore ContextType Attributions Associations Parents Children + ConvertContext(source *proto.Context) (*db.Context, error) + // goverter:map ID Id + // goverter:map ID Type | ConvertTypeIDToName + // goverter:map Properties | ConvertToProtoContextProperties + // goverter:map Properties CustomProperties | ConvertToProtoContextCustomProperties + // goverter:ignore state sizeCache unknownFields SystemMetadata + ConvertToContext(source *db.Context) (*proto.Context, error) + + // goverter:map LastKnownState | ConvertExecution_State + // goverter:map . Properties | ConvertProtoExecutionProperties + // goverter:ignore ExecutionType Associations Events + ConvertExecution(source *proto.Execution) (*db.Execution, error) + // goverter:map ID Id + // goverter:map ID Type | ConvertTypeIDToName + // goverter:map LastKnownState | ConvertToExecution_State + // goverter:map Properties | ConvertToProtoExecutionProperties + // goverter:map Properties CustomProperties | ConvertToProtoExecutionCustomProperties + // goverter:ignore state sizeCache unknownFields SystemMetadata + ConvertToExecution(source *db.Execution) (*proto.Execution, error) + + // goverter:map Type | ConvertProtoEventType + // goverter:map Path PathSteps | ConvertProtoEventPath + // goverter:ignore ID Artifact Execution + ConvertEvent(source *proto.Event) (*db.Event, error) + // goverter:map Type | ConvertToProtoEventType + // goverter:map PathSteps Path | ConvertToProtoEventPath + // goverter:ignore state sizeCache unknownFields SystemMetadata + ConvertToEvent(source *db.Event) (*proto.Event, error) + + // goverter:ignore ID Context Artifact + ConvertAttribution(source *proto.Attribution) (*db.Attribution, error) + // goverter:ignore ID state sizeCache unknownFields + ConvertToAttribution(source *db.Attribution) (*proto.Attribution, error) + + // goverter:ignore ID Context Execution + ConvertAssociation(source *proto.Association) (*db.Association, error) + // goverter:ignore state sizeCache unknownFields + ConvertToAssociation(source *db.Association) (*proto.Association, error) +} diff --git a/internal/converter/grpc_converter_util.go b/internal/converter/grpc_converter_util.go new file mode 100644 index 00000000..57efbab4 --- /dev/null +++ b/internal/converter/grpc_converter_util.go @@ -0,0 +1,355 @@ +package converter + +import ( + "fmt" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/db" + "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/structpb" +) + +func ConvertTypeIDToName(id int64) (*string, error) { + if id == 0 { + return nil, nil + } + if globalDB == nil { + return nil, fmt.Errorf("converter DB connection has not been initialized") + } + var name string + if err := globalDB.Model(db.Type{}).Select("name").Where("id = ?", id).First(&name).Error; err != nil { + return nil, fmt.Errorf("error getting type name for type id %d: %w", id, err) + } + return &name, nil +} + +func ConvertToProtoArtifactProperties(source []db.ArtifactProperty) (map[string]*proto.Value, error) { + result := make(map[string]*proto.Value) + for _, prop := range source { + var p db.MetadataProperty = &prop + if !p.GetIsCustomProperty() { + value, err := convertToProtoValue(p) + if err != nil { + return nil, err + } + result[p.GetName()] = value + } + } + return result, nil +} + +func ConvertToProtoArtifactCustomProperties(source []db.ArtifactProperty) (map[string]*proto.Value, error) { + result := make(map[string]*proto.Value) + for _, prop := range source { + var p db.MetadataProperty = &prop + if p.GetIsCustomProperty() { + value, err := convertToProtoValue(p) + if err != nil { + return nil, err + } + result[p.GetName()] = value + } + } + return result, nil +} + +func ConvertToProtoContextProperties(source []db.ContextProperty) (map[string]*proto.Value, error) { + result := make(map[string]*proto.Value) + for _, prop := range source { + var p db.MetadataProperty = &prop + if !p.GetIsCustomProperty() { + value, err := convertToProtoValue(p) + if err != nil { + return nil, err + } + result[p.GetName()] = value + } + } + return result, nil +} + +func ConvertToProtoContextCustomProperties(source []db.ContextProperty) (map[string]*proto.Value, error) { + result := make(map[string]*proto.Value) + for _, prop := range source { + var p db.MetadataProperty = &prop + if p.GetIsCustomProperty() { + value, err := convertToProtoValue(p) + if err != nil { + return nil, err + } + result[p.GetName()] = value + } + } + return result, nil +} + +func ConvertToProtoExecutionProperties(source []db.ExecutionProperty) (map[string]*proto.Value, error) { + result := make(map[string]*proto.Value) + for _, prop := range source { + var p db.MetadataProperty = &prop + if !p.GetIsCustomProperty() { + value, err := convertToProtoValue(p) + if err != nil { + return nil, err + } + result[p.GetName()] = value + } + } + return result, nil +} + +func ConvertToProtoExecutionCustomProperties(source []db.ExecutionProperty) (map[string]*proto.Value, error) { + result := make(map[string]*proto.Value) + for _, prop := range source { + var p db.MetadataProperty = &prop + if p.GetIsCustomProperty() { + value, err := convertToProtoValue(p) + if err != nil { + return nil, err + } + result[p.GetName()] = value + } + } + return result, nil +} + +func convertToProtoValue(prop db.MetadataProperty) (*proto.Value, error) { + result := proto.Value{} + if prop.GetIntValue() != nil { + result.Value = &proto.Value_IntValue{IntValue: *prop.GetIntValue()} + } + if prop.GetDoubleValue() != nil { + result.Value = &proto.Value_DoubleValue{DoubleValue: *prop.GetDoubleValue()} + } + if prop.GetStringValue() != nil { + result.Value = &proto.Value_StringValue{StringValue: *prop.GetStringValue()} + } + if prop.GetByteValue() != nil { + value := structpb.Struct{} + err := value.UnmarshalJSON(*prop.GetByteValue()) + if err != nil { + return nil, err + } + result.Value = &proto.Value_StructValue{StructValue: &value} + } + if prop.GetProtoValue() != nil { + value := anypb.Any{ + TypeUrl: *prop.GetTypeURL(), + Value: *prop.GetProtoValue(), + } + result.Value = &proto.Value_ProtoValue{ProtoValue: &value} + } + if prop.GetBoolValue() != nil { + result.Value = &proto.Value_BoolValue{BoolValue: *prop.GetBoolValue()} + } + return &result, nil +} + +func ConvertProtoArtifactProperties(source *proto.Artifact) ([]db.ArtifactProperty, error) { + var result []db.ArtifactProperty + var id int64 + if source.Id != nil { + id = *source.Id + } + err := convertArtifactProtoProperties(source.Properties, id, false, &result) + if err != nil { + return nil, err + } + err = convertArtifactProtoProperties(source.CustomProperties, id, true, &result) + if err != nil { + return nil, err + } + return result, nil +} + +func ConvertProtoContextProperties(source *proto.Context) ([]db.ContextProperty, error) { + var result []db.ContextProperty + var id int64 + if source.Id != nil { + id = *source.Id + } + err := convertContextProtoProperties(source.Properties, id, false, &result) + if err != nil { + return nil, err + } + err = convertContextProtoProperties(source.CustomProperties, id, true, &result) + if err != nil { + return nil, err + } + return result, nil +} + +func ConvertProtoExecutionProperties(source *proto.Execution) ([]db.ExecutionProperty, error) { + var result []db.ExecutionProperty + var id int64 + if source.Id != nil { + id = *source.Id + } + err := convertExecutionProtoProperties(source.Properties, id, false, &result) + if err != nil { + return nil, err + } + err = convertExecutionProtoProperties(source.CustomProperties, id, true, &result) + if err != nil { + return nil, err + } + return result, nil +} + +func convertArtifactProtoProperties(source map[string]*proto.Value, id int64, customProperty bool, result *[]db.ArtifactProperty) error { + for name, prop := range source { + if prop != nil { + ap := db.ArtifactProperty{Name: name, ArtifactID: id, IsCustomProperty: customProperty} + err := convertProtoValue(prop, &ap) + if err != nil { + return err + } + *result = append(*result, ap) + } + } + return nil +} + +func convertContextProtoProperties(source map[string]*proto.Value, id int64, customProperty bool, result *[]db.ContextProperty) error { + for name, prop := range source { + if prop != nil { + ap := db.ContextProperty{Name: name, ContextID: id, IsCustomProperty: customProperty} + err := convertProtoValue(prop, &ap) + if err != nil { + return err + } + *result = append(*result, ap) + } + } + return nil +} + +func convertExecutionProtoProperties(source map[string]*proto.Value, id int64, customProperty bool, result *[]db.ExecutionProperty) error { + for name, prop := range source { + if prop != nil { + ap := db.ExecutionProperty{Name: name, ExecutionID: id, IsCustomProperty: customProperty} + err := convertProtoValue(prop, &ap) + if err != nil { + return err + } + *result = append(*result, ap) + } + } + return nil +} + +func convertProtoValue(source *proto.Value, target db.MetadataProperty) error { + switch p := source.Value.(type) { + case *proto.Value_IntValue: + target.SetIntValue(&p.IntValue) + case *proto.Value_DoubleValue: + target.SetDoubleValue(&p.DoubleValue) + case *proto.Value_StringValue: + target.SetStringValue(&p.StringValue) + case *proto.Value_StructValue: + bytes, err := p.StructValue.MarshalJSON() + if err != nil { + return fmt.Errorf("error converting struct value: %w", err) + } + target.SetByteValue(&bytes) + case *proto.Value_ProtoValue: + target.SetTypeURL(&p.ProtoValue.TypeUrl) + target.SetProtoValue(&p.ProtoValue.Value) + case *proto.Value_BoolValue: + target.SetBoolValue(&p.BoolValue) + } + return nil +} + +func ConvertArtifact_State(source *proto.Artifact_State) *int8 { + if source == nil { + return nil + } + state := int8((*source).Number()) + return &state +} + +func ConvertToArtifact_State(source *int8) (*proto.Artifact_State, error) { + if source == nil { + return nil, nil + } + if _, ok := proto.Artifact_State_name[int32(*source)]; !ok { + return nil, fmt.Errorf("invalid artifact state %d", *source) + } + state := proto.Artifact_State(*source) + return &state, nil +} + +func ConvertExecution_State(source *proto.Execution_State) *int8 { + if source == nil { + return nil + } + state := int8((*source).Number()) + return &state +} + +func ConvertToExecution_State(source *int8) (*proto.Execution_State, error) { + if source == nil { + return nil, nil + } + if _, ok := proto.Execution_State_name[int32(*source)]; !ok { + return nil, fmt.Errorf("invalid execution state %d", *source) + } + state := proto.Execution_State(*source) + return &state, nil +} + +func ConvertProtoEventType(source *proto.Event_Type) int8 { + if source == nil { + return int8(proto.Event_UNKNOWN) + } + return int8((*source).Number()) +} + +func ConvertToProtoEventType(source int8) (*proto.Event_Type, error) { + if _, ok := proto.Event_Type_name[int32(source)]; !ok { + return nil, fmt.Errorf("invalid event type %d", source) + } + state := proto.Event_Type(source) + return &state, nil +} + +func ConvertProtoEventPath(source *proto.Event_Path) ([]db.EventPath, error) { + var result []db.EventPath + if source != nil { + for _, step := range source.Steps { + switch s := step.Value.(type) { + case *proto.Event_Path_Step_Index: + i := int(s.Index) + result = append(result, db.EventPath{ + IsIndexStep: true, + StepIndex: &i, + }) + case *proto.Event_Path_Step_Key: + result = append(result, db.EventPath{ + IsIndexStep: false, + StepKey: &s.Key, + }) + } + } + } + return result, nil +} + +func ConvertToProtoEventPath(source []db.EventPath) (*proto.Event_Path, error) { + if len(source) == 0 { + return nil, nil + } + var result proto.Event_Path + for _, step := range source { + if step.IsIndexStep { + result.Steps = append(result.Steps, &proto.Event_Path_Step{ + Value: &proto.Event_Path_Step_Index{Index: int64(*step.StepIndex)}, + }) + } else { + result.Steps = append(result.Steps, &proto.Event_Path_Step{ + Value: &proto.Event_Path_Step_Key{Key: *step.StepKey}, + }) + } + } + return &result, nil +} From 4adb60da81c40815f47ad391ece02a07364f5a17 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 27 Sep 2023 10:17:47 -0700 Subject: [PATCH 057/254] Add unit test for grpc converter utility functions --- .../converter/grpc_converter_util_test.go | 875 ++++++++++++++++++ 1 file changed, 875 insertions(+) create mode 100644 internal/converter/grpc_converter_util_test.go diff --git a/internal/converter/grpc_converter_util_test.go b/internal/converter/grpc_converter_util_test.go new file mode 100644 index 00000000..6154e876 --- /dev/null +++ b/internal/converter/grpc_converter_util_test.go @@ -0,0 +1,875 @@ +package converter + +import ( + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/db" + "google.golang.org/protobuf/types/known/anypb" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/logger" + "log" + "os" + "reflect" + "testing" + "time" +) + +func TestConvertArtifact_State(t *testing.T) { + type args struct { + source *proto.Artifact_State + } + pending := proto.Artifact_PENDING + var pendingInt int8 = 1 + tests := []struct { + name string + args args + want *int8 + }{ + { + name: "valid state", + args: args{source: &pending}, + want: &pendingInt, + }, + { + name: "nil state", + args: args{source: nil}, + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ConvertArtifact_State(tt.args.source); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertArtifact_State() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToArtifact_State(t *testing.T) { + type args struct { + source *int8 + } + pendingState := int8(db.PENDING) + pendingProto := proto.Artifact_PENDING + invalidState := int8(-1) + tests := []struct { + name string + args args + want *proto.Artifact_State + wantErr bool + }{ + { + name: "valid state", + args: args{source: &pendingState}, + want: &pendingProto, + wantErr: false, + }, + { + name: "invalid state", + args: args{source: &invalidState}, + want: nil, + wantErr: true, + }, + { + name: "nil state", + args: args{source: nil}, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToArtifact_State(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToArtifact_State() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToArtifact_State() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertExecution_State(t *testing.T) { + type args struct { + source *proto.Execution_State + } + newState := proto.Execution_NEW + newResult := int8(db.NEW) + tests := []struct { + name string + args args + want *int8 + }{ + { + name: "valid state", + args: args{source: &newState}, + want: &newResult, + }, + { + name: "nil state", + args: args{source: nil}, + want: nil, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ConvertExecution_State(tt.args.source); !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertExecution_State() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToExecution_State(t *testing.T) { + type args struct { + source *int8 + } + newState := int8(db.NEW) + newProtoState := proto.Execution_NEW + invalidState := int8(-1) + tests := []struct { + name string + args args + want *proto.Execution_State + wantErr bool + }{ + { + name: "valid state", + args: args{source: &newState}, + want: &newProtoState, + wantErr: false, + }, + { + name: "invalid state", + args: args{source: &invalidState}, + want: nil, + wantErr: true, + }, + { + name: "nil state", + args: args{source: nil}, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToExecution_State(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToExecution_State() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToExecution_State() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertProtoArtifactProperties(t *testing.T) { + type args struct { + source *proto.Artifact + } + testStr := "test" + intValue := int64(10) + boolValue := true + doubleValue := 98.6 + tests := []struct { + name string + args args + want []db.ArtifactProperty + wantErr bool + }{ + { + name: "nil artifact id", + args: args{source: &proto.Artifact{ + Id: nil, + Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, + CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, + }}, + want: []db.ArtifactProperty{ + {Name: "prop1", StringValue: &testStr}, + {Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, + }, + wantErr: false, + }, + { + name: "valid artifact id", + args: args{source: &proto.Artifact{ + Id: &intValue, + Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_DoubleValue{DoubleValue: doubleValue}}}, + CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_BoolValue{BoolValue: boolValue}}}, + }}, + want: []db.ArtifactProperty{ + {ArtifactID: intValue, Name: "prop1", DoubleValue: &doubleValue}, + {ArtifactID: intValue, Name: "prop2", IsCustomProperty: true, BoolValue: &boolValue}, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertProtoArtifactProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertProtoArtifactProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertProtoArtifactProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertProtoContextProperties(t *testing.T) { + type args struct { + source *proto.Context + } + testStr := "test" + intValue := int64(10) + tests := []struct { + name string + args args + want []db.ContextProperty + wantErr bool + }{ + { + name: "nil context id", + args: args{source: &proto.Context{ + Id: nil, + Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, + CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, + }}, + want: []db.ContextProperty{ + {Name: "prop1", StringValue: &testStr}, + {Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, + }, + wantErr: false, + }, + { + name: "valid context id", + args: args{source: &proto.Context{ + Id: &intValue, + Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, + CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, + }}, + want: []db.ContextProperty{ + {ContextID: intValue, Name: "prop1", StringValue: &testStr}, + {ContextID: intValue, Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertProtoContextProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertProtoContextProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertProtoContextProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertProtoEventPath(t *testing.T) { + type args struct { + source *proto.Event_Path + } + stepIndex := 1 + stepKey := "my-key" + tests := []struct { + name string + args args + want []db.EventPath + wantErr bool + }{ + { + name: "step index", + args: args{source: &proto.Event_Path{Steps: []*proto.Event_Path_Step{{Value: &proto.Event_Path_Step_Index{Index: int64(stepIndex)}}}}}, + want: []db.EventPath{{IsIndexStep: true, StepIndex: &stepIndex}}, + wantErr: false, + }, + { + name: "step key", + args: args{source: &proto.Event_Path{Steps: []*proto.Event_Path_Step{{Value: &proto.Event_Path_Step_Key{Key: stepKey}}}}}, + want: []db.EventPath{{StepKey: &stepKey}}, + wantErr: false, + }, + { + name: "nil path", + args: args{}, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertProtoEventPath(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertProtoEventPath() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertProtoEventPath() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertProtoEventType(t *testing.T) { + type args struct { + source *proto.Event_Type + } + validEventType := proto.Event_DECLARED_INPUT + tests := []struct { + name string + args args + want int8 + }{ + { + name: "valid proto event type", + args: args{source: &validEventType}, + want: 2, + }, + { + name: "nil proto event type", + args: args{}, + want: int8(db.EVENT_TYPE_UNKNOWN), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ConvertProtoEventType(tt.args.source); got != tt.want { + t.Errorf("ConvertProtoEventType() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertProtoExecutionProperties(t *testing.T) { + type args struct { + source *proto.Execution + } + testStr := "test" + intValue := int64(10) + tests := []struct { + name string + args args + want []db.ExecutionProperty + wantErr bool + }{ + { + name: "nil execution id", + args: args{source: &proto.Execution{ + Id: nil, + Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, + CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, + }}, + want: []db.ExecutionProperty{ + {Name: "prop1", StringValue: &testStr}, + {Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, + }, + wantErr: false, + }, + { + name: "valid execution id", + args: args{source: &proto.Execution{ + Id: &intValue, + Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, + CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, + }}, + want: []db.ExecutionProperty{ + {ExecutionID: intValue, Name: "prop1", StringValue: &testStr}, + {ExecutionID: intValue, Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertProtoExecutionProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertProtoExecutionProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertProtoExecutionProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoArtifactCustomProperties(t *testing.T) { + type args struct { + source []db.ArtifactProperty + } + intValue := int64(1) + stringValue := "test" + bytes := []byte(stringValue) + tests := []struct { + name string + args args + want map[string]*proto.Value + wantErr bool + }{ + { + name: "valid custom properties", + args: args{source: []db.ArtifactProperty{ + {Name: "notCustomProp", IntValue: &intValue}, + {Name: "customProp", IsCustomProperty: true, StringValue: &stringValue}, + }}, + want: map[string]*proto.Value{"customProp": {Value: &proto.Value_StringValue{StringValue: stringValue}}}, + wantErr: false, + }, + { + name: "invalid bytes property", + args: args{source: []db.ArtifactProperty{ + {Name: "notCustomProp", IntValue: &intValue}, + {Name: "customProp", IsCustomProperty: true, ByteValue: &bytes}, + }}, + want: nil, + wantErr: true, + }, + { + name: "no properties", + want: map[string]*proto.Value{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoArtifactCustomProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoArtifactCustomProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoArtifactCustomProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoArtifactProperties(t *testing.T) { + type args struct { + source []db.ArtifactProperty + } + doubleValue := 98.6 + boolValue := true + bytes := []byte("test") + tests := []struct { + name string + args args + want map[string]*proto.Value + wantErr bool + }{ + { + name: "valid non-custom properties", + args: args{source: []db.ArtifactProperty{ + {Name: "notCustomProp", DoubleValue: &doubleValue}, + {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, + }}, + want: map[string]*proto.Value{"notCustomProp": {Value: &proto.Value_DoubleValue{DoubleValue: doubleValue}}}, + wantErr: false, + }, + { + name: "invalid bytes property", + args: args{source: []db.ArtifactProperty{ + {Name: "notCustomProp", ByteValue: &bytes}, + {Name: "customProp", IsCustomProperty: true, DoubleValue: &doubleValue}, + }}, + want: nil, + wantErr: true, + }, + { + name: "no properties", + want: map[string]*proto.Value{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoArtifactProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoArtifactProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoArtifactProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoContextCustomProperties(t *testing.T) { + type args struct { + source []db.ContextProperty + } + intValue := int64(1) + stringValue := "test" + bytes := []byte(stringValue) + boolValue := true + tests := []struct { + name string + args args + want map[string]*proto.Value + wantErr bool + }{ + { + name: "valid custom properties", + args: args{source: []db.ContextProperty{ + {Name: "notCustomProp", IntValue: &intValue}, + {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, + }}, + want: map[string]*proto.Value{"customProp": {Value: &proto.Value_BoolValue{BoolValue: boolValue}}}, + wantErr: false, + }, + { + name: "invalid bytes property", + args: args{source: []db.ContextProperty{ + {Name: "notCustomProp", IntValue: &intValue}, + {Name: "customProp", IsCustomProperty: true, ByteValue: &bytes}, + }}, + want: nil, + wantErr: true, + }, + { + name: "no properties", + want: map[string]*proto.Value{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoContextCustomProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoContextCustomProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoContextCustomProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoContextProperties(t *testing.T) { + type args struct { + source []db.ContextProperty + } + doubleValue := 98.6 + boolValue := true + bytes := []byte("test") + typeUrl := "url://test" + tests := []struct { + name string + args args + want map[string]*proto.Value + wantErr bool + }{ + { + name: "valid non-custom properties", + args: args{source: []db.ContextProperty{ + {Name: "notCustomProp", ProtoValue: &bytes, TypeURL: &typeUrl}, + {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, + }}, + want: map[string]*proto.Value{ + "notCustomProp": {Value: &proto.Value_ProtoValue{ProtoValue: &anypb.Any{TypeUrl: typeUrl, Value: bytes}}}, + }, + wantErr: false, + }, + { + name: "invalid bytes property", + args: args{source: []db.ContextProperty{ + {Name: "notCustomProp", ByteValue: &bytes}, + {Name: "customProp", IsCustomProperty: true, DoubleValue: &doubleValue}, + }}, + want: nil, + wantErr: true, + }, + { + name: "no properties", + want: map[string]*proto.Value{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoContextProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoContextProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoContextProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoEventPath(t *testing.T) { + type args struct { + source []db.EventPath + } + stepIndex := 1 + stepKey := "test" + tests := []struct { + name string + args args + want *proto.Event_Path + wantErr bool + }{ + { + name: "valid path index", + args: args{source: []db.EventPath{{IsIndexStep: true, StepIndex: &stepIndex}}}, + want: &proto.Event_Path{Steps: []*proto.Event_Path_Step{ + {Value: &proto.Event_Path_Step_Index{Index: int64(stepIndex)}}, + }}, + wantErr: false, + }, + { + name: "valid path key", + args: args{source: []db.EventPath{{StepKey: &stepKey}}}, + want: &proto.Event_Path{Steps: []*proto.Event_Path_Step{ + {Value: &proto.Event_Path_Step_Key{Key: stepKey}}, + }}, + wantErr: false, + }, + { + name: "nil path", + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoEventPath(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoEventPath() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoEventPath() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoEventType(t *testing.T) { + type args struct { + source int8 + } + validEventType := proto.Event_DECLARED_INPUT + unknownEventType := proto.Event_UNKNOWN + tests := []struct { + name string + args args + want *proto.Event_Type + wantErr bool + }{ + { + name: "valid event type", + args: args{source: int8(db.DECLARED_INPUT)}, + want: &validEventType, + wantErr: false, + }, + { + name: "nil event type", + args: args{}, + want: &unknownEventType, + wantErr: false, + }, + { + name: "invalid event type", + args: args{source: int8(-1)}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoEventType(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoEventType() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoEventType() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoExecutionCustomProperties(t *testing.T) { + type args struct { + source []db.ExecutionProperty + } + intValue := int64(1) + stringValue := "test" + bytes := []byte(stringValue) + boolValue := true + tests := []struct { + name string + args args + want map[string]*proto.Value + wantErr bool + }{ + { + name: "valid custom properties", + args: args{source: []db.ExecutionProperty{ + {Name: "notCustomProp", IntValue: &intValue}, + {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, + }}, + want: map[string]*proto.Value{"customProp": {Value: &proto.Value_BoolValue{BoolValue: boolValue}}}, + wantErr: false, + }, + { + name: "invalid bytes property", + args: args{source: []db.ExecutionProperty{ + {Name: "notCustomProp", IntValue: &intValue}, + {Name: "customProp", IsCustomProperty: true, ByteValue: &bytes}, + }}, + want: nil, + wantErr: true, + }, + { + name: "no properties", + want: map[string]*proto.Value{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoExecutionCustomProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoExecutionCustomProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoExecutionCustomProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertToProtoExecutionProperties(t *testing.T) { + type args struct { + source []db.ExecutionProperty + } + doubleValue := 98.6 + boolValue := true + bytes := []byte("test") + typeUrl := "url://test" + tests := []struct { + name string + args args + want map[string]*proto.Value + wantErr bool + }{ + { + name: "valid non-custom properties", + args: args{source: []db.ExecutionProperty{ + {Name: "notCustomProp", ProtoValue: &bytes, TypeURL: &typeUrl}, + {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, + }}, + want: map[string]*proto.Value{ + "notCustomProp": {Value: &proto.Value_ProtoValue{ProtoValue: &anypb.Any{TypeUrl: typeUrl, Value: bytes}}}, + }, + wantErr: false, + }, + { + name: "invalid bytes property", + args: args{source: []db.ExecutionProperty{ + {Name: "notCustomProp", ByteValue: &bytes}, + {Name: "customProp", IsCustomProperty: true, DoubleValue: &doubleValue}, + }}, + want: nil, + wantErr: true, + }, + { + name: "no properties", + want: map[string]*proto.Value{}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertToProtoExecutionProperties(tt.args.source) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertToProtoExecutionProperties() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertToProtoExecutionProperties() got = %v, want %v", got, tt.want) + } + }) + } +} + +func TestConvertTypeIDToName(t *testing.T) { + // setup mock DB + logger := logger.New( + log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer + logger.Config{ + SlowThreshold: time.Second, // Slow SQL threshold + LogLevel: logger.Info, // Log level + Colorful: true, // Disable color + }, + ) + dbConn, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{Logger: logger}) + if err != nil { + t.Errorf("failed to create mock Gorm connection: %v", err) + } + _ = dbConn.Migrator().AutoMigrate(db.Type{}) + _ = dbConn.Exec("INSERT INTO Type VALUES(1,'mlmd.Dataset',NULL,1,NULL,NULL,NULL,NULL)").Error + _ = dbConn.Exec("INSERT INTO Type VALUES(2,'mlmd.Model',NULL,1,NULL,NULL,NULL,NULL)").Error + SetConverterDB(dbConn) + + type args struct { + id int64 + } + dataSet := "mlmd.Dataset" + model := "mlmd.Model" + tests := []struct { + name string + args args + want *string + wantErr bool + }{ + { + name: dataSet, + args: args{id: 1}, + want: &dataSet, + wantErr: false, + }, + { + name: model, + args: args{id: 2}, + want: &model, + wantErr: false, + }, + { + name: "missing id", + args: args{id: 3}, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := ConvertTypeIDToName(tt.args.id) + if (err != nil) != tt.wantErr { + t.Errorf("ConvertTypeIDToName() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("ConvertTypeIDToName() got = %v, want %v", got, tt.want) + } + }) + } +} From ec62f3e65f5d37d55ab58f46a9ac26574f4d304f Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 28 Sep 2023 20:03:29 -0700 Subject: [PATCH 058/254] Code cleanup in grpc_converter_util, add Makefile test target --- .github/workflows/build.yml | 2 + Makefile | 4 ++ internal/converter/grpc_converter_util.go | 71 +++++++++-------------- 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 67bc1914..1c63e5d6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,3 +30,5 @@ jobs: run: make clean - name: Build run: make build + - name: Unit tests + run: make test diff --git a/Makefile b/Makefile index e285d637..02f5e507 100644 --- a/Makefile +++ b/Makefile @@ -72,6 +72,10 @@ lint: gen golangci-lint run main.go golangci-lint run cmd/... internal/... +.PHONY: test +test: gen + go test ./internal/... + .PHONY: run/migrate run/migrate: gen go run main.go migrate --logtostderr=true -m config/metadata-library diff --git a/internal/converter/grpc_converter_util.go b/internal/converter/grpc_converter_util.go index 57efbab4..796fa86d 100644 --- a/internal/converter/grpc_converter_util.go +++ b/internal/converter/grpc_converter_util.go @@ -25,13 +25,9 @@ func ConvertTypeIDToName(id int64) (*string, error) { func ConvertToProtoArtifactProperties(source []db.ArtifactProperty) (map[string]*proto.Value, error) { result := make(map[string]*proto.Value) for _, prop := range source { - var p db.MetadataProperty = &prop - if !p.GetIsCustomProperty() { - value, err := convertToProtoValue(p) - if err != nil { - return nil, err - } - result[p.GetName()] = value + err := convertToProtoMetadataProperty(&prop, result, false) + if err != nil { + return nil, err } } return result, nil @@ -40,13 +36,9 @@ func ConvertToProtoArtifactProperties(source []db.ArtifactProperty) (map[string] func ConvertToProtoArtifactCustomProperties(source []db.ArtifactProperty) (map[string]*proto.Value, error) { result := make(map[string]*proto.Value) for _, prop := range source { - var p db.MetadataProperty = &prop - if p.GetIsCustomProperty() { - value, err := convertToProtoValue(p) - if err != nil { - return nil, err - } - result[p.GetName()] = value + err := convertToProtoMetadataProperty(&prop, result, true) + if err != nil { + return nil, err } } return result, nil @@ -55,13 +47,9 @@ func ConvertToProtoArtifactCustomProperties(source []db.ArtifactProperty) (map[s func ConvertToProtoContextProperties(source []db.ContextProperty) (map[string]*proto.Value, error) { result := make(map[string]*proto.Value) for _, prop := range source { - var p db.MetadataProperty = &prop - if !p.GetIsCustomProperty() { - value, err := convertToProtoValue(p) - if err != nil { - return nil, err - } - result[p.GetName()] = value + err := convertToProtoMetadataProperty(&prop, result, false) + if err != nil { + return nil, err } } return result, nil @@ -70,13 +58,9 @@ func ConvertToProtoContextProperties(source []db.ContextProperty) (map[string]*p func ConvertToProtoContextCustomProperties(source []db.ContextProperty) (map[string]*proto.Value, error) { result := make(map[string]*proto.Value) for _, prop := range source { - var p db.MetadataProperty = &prop - if p.GetIsCustomProperty() { - value, err := convertToProtoValue(p) - if err != nil { - return nil, err - } - result[p.GetName()] = value + err := convertToProtoMetadataProperty(&prop, result, true) + if err != nil { + return nil, err } } return result, nil @@ -85,13 +69,9 @@ func ConvertToProtoContextCustomProperties(source []db.ContextProperty) (map[str func ConvertToProtoExecutionProperties(source []db.ExecutionProperty) (map[string]*proto.Value, error) { result := make(map[string]*proto.Value) for _, prop := range source { - var p db.MetadataProperty = &prop - if !p.GetIsCustomProperty() { - value, err := convertToProtoValue(p) - if err != nil { - return nil, err - } - result[p.GetName()] = value + err := convertToProtoMetadataProperty(&prop, result, false) + if err != nil { + return nil, err } } return result, nil @@ -100,18 +80,25 @@ func ConvertToProtoExecutionProperties(source []db.ExecutionProperty) (map[strin func ConvertToProtoExecutionCustomProperties(source []db.ExecutionProperty) (map[string]*proto.Value, error) { result := make(map[string]*proto.Value) for _, prop := range source { - var p db.MetadataProperty = &prop - if p.GetIsCustomProperty() { - value, err := convertToProtoValue(p) - if err != nil { - return nil, err - } - result[p.GetName()] = value + err := convertToProtoMetadataProperty(&prop, result, true) + if err != nil { + return nil, err } } return result, nil } +func convertToProtoMetadataProperty(p db.MetadataProperty, result map[string]*proto.Value, customProperty bool) error { + if p.GetIsCustomProperty() == customProperty { + value, err := convertToProtoValue(p) + if err != nil { + return err + } + result[p.GetName()] = value + } + return nil +} + func convertToProtoValue(prop db.MetadataProperty) (*proto.Value, error) { result := proto.Value{} if prop.GetIntValue() != nil { From 29a8eae7ed04c06681ab52d2bc96d8d6f8242a11 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 4 Oct 2023 11:19:19 -0700 Subject: [PATCH 059/254] Cache type ids and names for gRPC converter --- internal/converter/grpc_converter.go | 6 ++-- internal/converter/grpc_converter_util.go | 29 +++++++++++++++++++ .../converter/grpc_converter_util_test.go | 3 +- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/internal/converter/grpc_converter.go b/internal/converter/grpc_converter.go index 56d85d37..dae5ff18 100644 --- a/internal/converter/grpc_converter.go +++ b/internal/converter/grpc_converter.go @@ -1,6 +1,7 @@ package converter import ( + "fmt" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/db" "gorm.io/gorm" @@ -13,11 +14,12 @@ var ( // SetConverterDB must be called before using gRPC converters, // it uses the singleton DB connection to lookup type names -func SetConverterDB(db *gorm.DB) { +func SetConverterDB(db *gorm.DB) error { if globalDB != nil { - panic("converter global DB connection MUST only be set once") + return fmt.Errorf("converter global DB connection MUST only be set once") } globalDB = db + return initTypeNameCache() } // goverter:converter diff --git a/internal/converter/grpc_converter_util.go b/internal/converter/grpc_converter_util.go index 796fa86d..d54425e1 100644 --- a/internal/converter/grpc_converter_util.go +++ b/internal/converter/grpc_converter_util.go @@ -6,12 +6,37 @@ import ( "github.com/opendatahub-io/model-registry/internal/model/db" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" + "sync" ) +var typeNameCache = map[int64]string{} +var cacheMutex = sync.Mutex{} + +func initTypeNameCache() error { + cacheMutex.Lock() + defer cacheMutex.Unlock() + + var types []db.Type + if err := globalDB.Model(db.Type{}).Select("id", "name").Find(&types).Error; err != nil { + return fmt.Errorf("error initializing type id cache: %w", err) + } + for _, t := range types { + typeNameCache[t.ID] = t.Name + } + return nil +} + func ConvertTypeIDToName(id int64) (*string, error) { if id == 0 { return nil, nil } + + cacheMutex.Lock() + defer cacheMutex.Unlock() + + if name, ok := typeNameCache[id]; ok { + return &name, nil + } if globalDB == nil { return nil, fmt.Errorf("converter DB connection has not been initialized") } @@ -19,6 +44,10 @@ func ConvertTypeIDToName(id int64) (*string, error) { if err := globalDB.Model(db.Type{}).Select("name").Where("id = ?", id).First(&name).Error; err != nil { return nil, fmt.Errorf("error getting type name for type id %d: %w", id, err) } + + // update cache + typeNameCache[id] = name + return &name, nil } diff --git a/internal/converter/grpc_converter_util_test.go b/internal/converter/grpc_converter_util_test.go index 6154e876..b3e720b7 100644 --- a/internal/converter/grpc_converter_util_test.go +++ b/internal/converter/grpc_converter_util_test.go @@ -827,8 +827,9 @@ func TestConvertTypeIDToName(t *testing.T) { } _ = dbConn.Migrator().AutoMigrate(db.Type{}) _ = dbConn.Exec("INSERT INTO Type VALUES(1,'mlmd.Dataset',NULL,1,NULL,NULL,NULL,NULL)").Error + _ = SetConverterDB(dbConn) + // add a new type after the converter cache is initialized _ = dbConn.Exec("INSERT INTO Type VALUES(2,'mlmd.Model',NULL,1,NULL,NULL,NULL,NULL)").Error - SetConverterDB(dbConn) type args struct { id int64 From ae4ca207b2b623ffc19c3a7184514876f8458337 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Tue, 10 Oct 2023 21:58:38 +0200 Subject: [PATCH 060/254] Define the Model Registry OpenAPI (#51) * Define the Model Registry OpenAPI Co-authored-by: Andrea Lamparelli * Update api/openapi/modelregistry.yml Co-authored-by: Andrea Lamparelli --------- Co-authored-by: Andrea Lamparelli --- api/openapi/modelregistry.yml | 369 ++++++++++++++++++++++++++++++++++ 1 file changed, 369 insertions(+) create mode 100644 api/openapi/modelregistry.yml diff --git a/api/openapi/modelregistry.yml b/api/openapi/modelregistry.yml new file mode 100644 index 00000000..62f2e4ac --- /dev/null +++ b/api/openapi/modelregistry.yml @@ -0,0 +1,369 @@ +openapi: 3.0.2 +info: + title: Model Registry API + version: 1.0.0 + description: 'See also https://github.com/opendatahub-io/model-registry/issues/44#issue-1919724627' +paths: + /environments: + summary: Path used to manage the list of environments. + description: >- + The REST endpoint/path used to list and create zero or more `Environment` entities. This path + contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + get: + responses: + '200': + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Environment' + description: Successful response - returns an array of `Environment` entities. + operationId: getEnvironments + summary: List All Environments + description: Gets a list of all `Environment` entities. + post: + requestBody: + description: A new `Environment` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/Environment' + required: true + responses: + '201': + description: Successful response. + operationId: createEnvironment + summary: Create a Environment + description: Creates a new instance of a `Environment`. + delete: + parameters: + - + name: name + description: '' + schema: {} + in: query + responses: + '200': + description: Successfully deleted `Environment` having `name`. + summary: Delete an Environment + description: 'Placed here only to avoid subpaths, can be re-drawn.' + /search: + description: |- + TBD: We feel this might be redundant with `models/` and `models/{name}`. + We suggest instead to: + 1. avoid usage of Query param (that might "explode" as search grows) + 2. provide search criteria in the body + get: + responses: + '200': + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/RegisteredModel' + description: Get all `RegisteredModel`s matching the supplied criteria. + summary: Search models + parameters: + - + name: name + description: '' + schema: + type: string + in: query + - + name: id + description: '' + schema: + type: string + in: query + - + name: tag + description: '' + schema: + type: string + in: query + - + name: label + description: '' + schema: + type: string + in: query + /models: + get: + responses: + '200': + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/RegisteredModel' + description: List all + summary: List all Models + description: List all `RegisteredModel` and belonging `VersionedModel`(s). + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VersionedModel' + required: true + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/VersionedModel' + description: Successfully created a `VersionedModel` for a Registered model. + summary: Assign a version to a registered model + description: |- + If a `RegisteredModel` for `model_name` already exists, this `VersionedModel` + will be assigned to it, else a new `RegisteredModel` will be created. + If a `model_name` is not provided, a random one will be used. + + The `id` is generated in the backend by the registry. + It could be implemented as a progressive number, to be decided. + The `id`s are unique within a RegisteredModel. + + The `version` is a user-provided symbolic name, for instance semantic versioning + The `version` if provided must be unique and non-already-existing within a + RegisterdModel and must not be the same as any of the `id`s. + '/models/{name}/versions/{version}': + get: + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/VersionedModel' + description: get `VersionedModel` for model name and version + summary: Get Version details + delete: + responses: + '200': + description: Successfully archive a `VersionedModel`. + summary: Archive a VersionedModel + description: 'This does NOT delete any `VersionedModel`, but archives and deprecate it.' + patch: + requestBody: + description: 'The `uri`, `id`, `version` and other non-updatable fields will be ignored.' + content: + application/json: + schema: + $ref: '#/components/schemas/VersionedModel' + required: true + responses: + '200': + description: Successfully upated a `VersionedModel` in the updatable and provided fields. + description: |- + Updates a `VersionedModel` only for the updatable fields, such as label, tags, + description. + + Some fields will not be updated even if supplied, such as `model_uri`, `id`, + `version`. + parameters: + - + name: name + schema: + type: string + in: path + required: true + - + name: version + schema: + type: string + in: path + required: true + '/models/{name}': + get: + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/RegisteredModel' + description: Retrieves the `RegisteredModel`. + summary: Return a given RegisteredModel + post: + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/VersionedModel' + responses: + '200': + description: Successfully registered a versionedmodel under a registered model. + summary: Register a VersionedModel under a given name + description: |- + TBD: this as a potential alternative or complementary of `/models` POST + where the model's name is provided as a Path param instead. + parameters: + - + name: name + schema: + type: string + in: path + required: true +components: + schemas: + Environment: + title: Root Type for Environment + description: '' + type: object + properties: + name: + type: string + uri: + type: string + example: + name: My Environment + uri: 'http://localhost:8080' + RegisteredModel: + title: Root Type for RegisteredModel + description: '' + type: object + properties: + name: + type: string + labels: + type: array + items: + type: string + versions: + type: array + items: + $ref: '#/components/schemas/VersionedModel' + example: + name: my ML pricing model + labels: + - tutorial + - linreg + versions: + - + model_name: my ML pricing model + id: ae123-78932-64893 + version: v1 + model_uri: 's3://89492-46893-54692' + tags: + - Staging + labels: + - tutorial + - linreg + environments: + - + name: My Environment + uri: 'http://localhost:8080' + created date: '20231002T12:34:56' + updated date: '20231002T12:34:56' + author: 'John Doe, data scientist' + origin: 'dsp://123' + metadata: + accuracy: 99 + artifacts: + - + name: dataset + type: csv + uri: 's3://67489-46393-63469' + metadata: + authority: US Census + VersionedModel: + title: Root Type for VersionedModel + description: '' + required: + - model_uri + type: object + properties: + id: + type: string + version: + type: string + tags: + type: array + items: + type: string + labels: + type: array + items: + type: string + environments: + type: array + items: + $ref: '#/components/schemas/Environment' + created date: + format: date-time + type: string + updated date: + format: date-time + type: string + model_name: + type: string + author: + description: '' + type: string + example: '"John Doe, data scientist"' + metadata: + description: '' + type: object + model_uri: + description: '' + type: string + artifacts: + description: '' + type: array + items: + $ref: '#/components/schemas/Artifact' + origin: + description: 'For instance, the DSP id which realized the model' + type: string + example: + model_name: my ML pricing model + id: ae123-78932-64893 + version: v1 + model_uri: 's3://89492-46893-54692' + tags: + - Staging + labels: + - tutorial + - linreg + environments: + - + name: My Environment + uri: 'http://localhost:8080' + created date: '20231002T12:34:56' + updated date: '20231002T12:34:56' + author: 'John Doe, data scientist' + origin: 'dsp://123' + metadata: + accuracy: 99 + artifacts: + - + name: dataset + type: csv + uri: 's3://67489-46393-63469' + metadata: + authority: US Census + Artifact: + title: Root Type for Artifact + description: '' + type: object + properties: + type: + type: string + uri: + type: string + metadata: + type: object + properties: + authority: + type: string + name: + description: '' + type: string + example: + name: dataset + type: csv + uri: 's3://67489-46393-63469' + metadata: + authority: US Census From e9991bcdd21ba8ce11144417a49ba46103a57d45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 12 Oct 2023 13:57:25 +0200 Subject: [PATCH 061/254] Bump golang.org/x/net from 0.14.0 to 0.17.0 (#69) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.14.0 to 0.17.0. - [Commits](https://github.com/golang/net/compare/v0.14.0...v0.17.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 9a1bfbc8..42b125ac 100644 --- a/go.mod +++ b/go.mod @@ -46,9 +46,9 @@ require ( github.com/urfave/cli/v2 v2.25.5 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.14.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.9.3 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 8d23e819..df978020 100644 --- a/go.sum +++ b/go.sum @@ -304,8 +304,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -363,8 +363,8 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -374,8 +374,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 5ef8c07d6a81927e1457beb5bc199aadea29204c Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Fri, 13 Oct 2023 08:01:41 +0200 Subject: [PATCH 062/254] Extend GHA to cover for Docker build (#64) --- .github/workflows/container-image.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/container-image.yml diff --git a/.github/workflows/container-image.yml b/.github/workflows/container-image.yml new file mode 100644 index 00000000..27833bbb --- /dev/null +++ b/.github/workflows/container-image.yml @@ -0,0 +1,15 @@ +name: Test Container Image build + +on: + push: + branches: [ 'main' ] + pull_request: + branches: [ '*' ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build the Docker image + run: docker build . --file Dockerfile --tag model-registry:$(date +%s) From b27dc7cce15ee6c131620c77f63dffffa9945d5c Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Mon, 16 Oct 2023 07:09:01 +0200 Subject: [PATCH 063/254] Enhance GHA to check uncommitted changes (#63) * Enhance GHA to check uncommitted changes * Test GHA output deliberately * Revert "Test GHA output deliberately" used for GHA testing This reverts commit 065eb59ebad105ff891e3ff256c0645a50107f84 which was used for GHA testing --- .github/workflows/build.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1c63e5d6..88729661 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,5 +30,15 @@ jobs: run: make clean - name: Build run: make build + - name: Check if there are uncommitted file changes + run: | + clean=$(git status --porcelain) + if [[ -z "$clean" ]]; then + echo "Empty git status --porcelain: $clean" + else + echo "Uncommitted file changes detected: $clean" + git diff + exit 1 + fi - name: Unit tests run: make test From c664d5fe9d5ff9b0bc196bb165cbed3c9c086b32 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Tue, 17 Oct 2023 09:48:35 +0200 Subject: [PATCH 064/254] Add build status badge on README (#71) --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 01efcef7..fb32a5ba 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# model-registry +# Model Registry + +![build checks status](https://github.com/opendatahub-io/model-registry/actions/workflows/build.yml/badge.svg?branch=main) + A go based server that implements a gRPC interface for [ml_metadata](https://github.com/google/ml-metadata/) library. It adds other features on top of the functionality offered by the gRPC interface. ## Pre-requisites: From 659ec4e7768f700d5cec2897b720f05a3fd4d4c1 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Wed, 18 Oct 2023 09:15:17 -0700 Subject: [PATCH 065/254] Refactor model registry openapi definition. (#66) * Refactor openapi definition * Add name query parameter for model_version url, fix Artifact oneOf definition * Added sortOrder query param * Fix allOf composites for BaseArtifactUpdate and ModelArtifactUpdate * Add model-serving metadata resources, openapi-generator-cli, and generated model, server, and proxy cmd * Fix allOf types for InferenceServiceCreate and InferenceServiceUpdate --- .openapi-generator-ignore | 47 + Dockerfile | 7 +- Makefile | 53 +- README.md | 9 + api/openapi/model-registry.yaml | 1717 +++++ api/openapi/modelregistry.yml | 369 -- cmd/proxy.go | 50 + go.mod | 1 + go.sum | 2 + .../model/openapi/.openapi-generator/FILES | 53 + .../model/openapi/.openapi-generator/VERSION | 1 + .../openapi/api_model_registry_service.go | 5552 +++++++++++++++++ internal/model/openapi/client.go | 666 ++ internal/model/openapi/configuration.go | 217 + internal/model/openapi/model_artifact.go | 123 + internal/model/openapi/model_artifact_list.go | 209 + .../model/openapi/model_artifact_state.go | 120 + internal/model/openapi/model_base_artifact.go | 414 ++ .../openapi/model_base_artifact_create.go | 276 + .../openapi/model_base_artifact_update.go | 239 + .../model/openapi/model_base_execution.go | 350 ++ .../openapi/model_base_execution_create.go | 239 + .../openapi/model_base_execution_update.go | 202 + internal/model/openapi/model_base_resource.go | 310 + .../openapi/model_base_resource_create.go | 199 + .../model/openapi/model_base_resource_list.go | 172 + .../openapi/model_base_resource_update.go | 162 + internal/model/openapi/model_error.go | 144 + .../model/openapi/model_execution_state.go | 120 + .../model/openapi/model_inference_service.go | 403 ++ .../openapi/model_inference_service_create.go | 292 + .../openapi/model_inference_service_list.go | 209 + .../openapi/model_inference_service_update.go | 199 + .../model/openapi/model_metadata_value.go | 265 + .../openapi/model_metadata_value_one_of.go | 124 + .../openapi/model_metadata_value_one_of_1.go | 124 + .../openapi/model_metadata_value_one_of_2.go | 124 + .../openapi/model_metadata_value_one_of_3.go | 125 + .../openapi/model_metadata_value_one_of_4.go | 162 + .../openapi/model_metadata_value_one_of_5.go | 124 + .../model/openapi/model_model_artifact.go | 636 ++ .../openapi/model_model_artifact_create.go | 498 ++ .../openapi/model_model_artifact_list.go | 209 + .../openapi/model_model_artifact_update.go | 461 ++ internal/model/openapi/model_model_version.go | 310 + .../openapi/model_model_version_create.go | 226 + .../model/openapi/model_model_version_list.go | 209 + .../openapi/model_model_version_update.go | 162 + .../model/openapi/model_order_by_field.go | 112 + .../model/openapi/model_registered_model.go | 310 + .../openapi/model_registered_model_create.go | 199 + .../openapi/model_registered_model_list.go | 209 + .../openapi/model_registered_model_update.go | 162 + internal/model/openapi/model_serve_model.go | 378 ++ .../model/openapi/model_serve_model_create.go | 267 + .../model/openapi/model_serve_model_list.go | 209 + .../model/openapi/model_serve_model_update.go | 202 + .../openapi/model_serving_environment.go | 310 + .../model_serving_environment_create.go | 199 + .../openapi/model_serving_environment_list.go | 209 + .../model_serving_environment_update.go | 162 + internal/model/openapi/model_sort_order.go | 110 + internal/model/openapi/response.go | 47 + internal/model/openapi/utils.go | 347 ++ .../server/openapi/.openapi-generator/FILES | 55 + .../server/openapi/.openapi-generator/VERSION | 1 + internal/server/openapi/api.go | 99 + .../openapi/api_model_registry_service.go | 948 +++ .../api_model_registry_service_service.go | 764 +++ internal/server/openapi/error.go | 62 + internal/server/openapi/helpers.go | 60 + internal/server/openapi/impl.go | 16 + internal/server/openapi/logger.go | 32 + internal/server/openapi/routers.go | 297 + internal/server/openapi/type_asserts.go | 652 ++ openapitools.json | 7 + 76 files changed, 22936 insertions(+), 374 deletions(-) create mode 100644 .openapi-generator-ignore create mode 100644 api/openapi/model-registry.yaml delete mode 100644 api/openapi/modelregistry.yml create mode 100644 cmd/proxy.go create mode 100644 internal/model/openapi/.openapi-generator/FILES create mode 100644 internal/model/openapi/.openapi-generator/VERSION create mode 100644 internal/model/openapi/api_model_registry_service.go create mode 100644 internal/model/openapi/client.go create mode 100644 internal/model/openapi/configuration.go create mode 100644 internal/model/openapi/model_artifact.go create mode 100644 internal/model/openapi/model_artifact_list.go create mode 100644 internal/model/openapi/model_artifact_state.go create mode 100644 internal/model/openapi/model_base_artifact.go create mode 100644 internal/model/openapi/model_base_artifact_create.go create mode 100644 internal/model/openapi/model_base_artifact_update.go create mode 100644 internal/model/openapi/model_base_execution.go create mode 100644 internal/model/openapi/model_base_execution_create.go create mode 100644 internal/model/openapi/model_base_execution_update.go create mode 100644 internal/model/openapi/model_base_resource.go create mode 100644 internal/model/openapi/model_base_resource_create.go create mode 100644 internal/model/openapi/model_base_resource_list.go create mode 100644 internal/model/openapi/model_base_resource_update.go create mode 100644 internal/model/openapi/model_error.go create mode 100644 internal/model/openapi/model_execution_state.go create mode 100644 internal/model/openapi/model_inference_service.go create mode 100644 internal/model/openapi/model_inference_service_create.go create mode 100644 internal/model/openapi/model_inference_service_list.go create mode 100644 internal/model/openapi/model_inference_service_update.go create mode 100644 internal/model/openapi/model_metadata_value.go create mode 100644 internal/model/openapi/model_metadata_value_one_of.go create mode 100644 internal/model/openapi/model_metadata_value_one_of_1.go create mode 100644 internal/model/openapi/model_metadata_value_one_of_2.go create mode 100644 internal/model/openapi/model_metadata_value_one_of_3.go create mode 100644 internal/model/openapi/model_metadata_value_one_of_4.go create mode 100644 internal/model/openapi/model_metadata_value_one_of_5.go create mode 100644 internal/model/openapi/model_model_artifact.go create mode 100644 internal/model/openapi/model_model_artifact_create.go create mode 100644 internal/model/openapi/model_model_artifact_list.go create mode 100644 internal/model/openapi/model_model_artifact_update.go create mode 100644 internal/model/openapi/model_model_version.go create mode 100644 internal/model/openapi/model_model_version_create.go create mode 100644 internal/model/openapi/model_model_version_list.go create mode 100644 internal/model/openapi/model_model_version_update.go create mode 100644 internal/model/openapi/model_order_by_field.go create mode 100644 internal/model/openapi/model_registered_model.go create mode 100644 internal/model/openapi/model_registered_model_create.go create mode 100644 internal/model/openapi/model_registered_model_list.go create mode 100644 internal/model/openapi/model_registered_model_update.go create mode 100644 internal/model/openapi/model_serve_model.go create mode 100644 internal/model/openapi/model_serve_model_create.go create mode 100644 internal/model/openapi/model_serve_model_list.go create mode 100644 internal/model/openapi/model_serve_model_update.go create mode 100644 internal/model/openapi/model_serving_environment.go create mode 100644 internal/model/openapi/model_serving_environment_create.go create mode 100644 internal/model/openapi/model_serving_environment_list.go create mode 100644 internal/model/openapi/model_serving_environment_update.go create mode 100644 internal/model/openapi/model_sort_order.go create mode 100644 internal/model/openapi/response.go create mode 100644 internal/model/openapi/utils.go create mode 100644 internal/server/openapi/.openapi-generator/FILES create mode 100644 internal/server/openapi/.openapi-generator/VERSION create mode 100644 internal/server/openapi/api.go create mode 100644 internal/server/openapi/api_model_registry_service.go create mode 100644 internal/server/openapi/api_model_registry_service_service.go create mode 100644 internal/server/openapi/error.go create mode 100644 internal/server/openapi/helpers.go create mode 100644 internal/server/openapi/impl.go create mode 100644 internal/server/openapi/logger.go create mode 100644 internal/server/openapi/routers.go create mode 100644 internal/server/openapi/type_asserts.go create mode 100644 openapitools.json diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore new file mode 100644 index 00000000..40209379 --- /dev/null +++ b/.openapi-generator-ignore @@ -0,0 +1,47 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md + +# model and client files +internal/model/openapi/api +internal/model/openapi/api/** +internal/model/openapi/git_push.sh +internal/model/openapi/.gitignore +internal/model/openapi/.travis.yml +internal/model/openapi/.openapi-generator-ignore + +internal/model/openapi/README.md +internal/model/openapi/docs/**.md +internal/model/openapi/test +internal/model/openapi/test/** +internal/model/openapi/**all_of.go +internal/model/openapi/go.mod +internal/model/openapi/go.sum + +# server files to ignore +internal/server/openapi/api +internal/server/openapi/api/** +internal/server/openapi/.openapi-generator-ignore +internal/server/openapi/README.md +internal/server/openapi/main.go +internal/server/openapi/model_*.go diff --git a/Dockerfile b/Dockerfile index 234dc71b..d18777c1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,9 +8,12 @@ COPY ["go.mod", "go.sum", "./"] # and so that source changes don't invalidate our downloaded layer RUN go mod download -# Copy the go source USER root -COPY ["Makefile", "main.go", "gqlgen.yml", "./"] +# install npm and java for openapi-generator-cli +RUN yum install -y nodejs npm java-11 + +# Copy the go source +COPY ["Makefile", "main.go", "gqlgen.yml", ".openapi-generator-ignore", "openapitools.json", "./"] # Download protoc compiler v24.3 RUN wget -q https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-linux-x86_64.zip -O protoc.zip && \ diff --git a/Makefile b/Makefile index 02f5e507..789e60db 100644 --- a/Makefile +++ b/Makefile @@ -26,13 +26,38 @@ gen/graph: internal/model/graph/models_gen.go internal/model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml gqlgen generate +# validate the openapi schema +.PHONY: openapi/validate +openapi/validate: bin/openapi-generator-cli + openapi-generator-cli validate -i api/openapi/model-registry.yaml + +# generate the openapi server implementation +# note: run manually only when model-registry.yaml api changes, for model changes gen/openapi is run automatically +.PHONY: gen/openapi-server +gen/openapi-server: bin/openapi-generator-cli openapi/validate + openapi-generator-cli generate \ + -i api/openapi/model-registry.yaml -g go-server -o internal/server/openapi --package-name openapi \ + --ignore-file-override ./.openapi-generator-ignore --additional-properties=outputAsLibrary=true,enumClassPrefix=true,router=chi,sourceFolder=,onlyInterfaces=true + gofmt -w internal/server/openapi + +# generate the openapi schema model and client +.PHONY: gen/openapi +gen/openapi: bin/openapi-generator-cli openapi/validate internal/model/openapi/client.go + +internal/model/openapi/client.go: api/openapi/model-registry.yaml + rm -rf internal/model/openapi + openapi-generator-cli generate \ + -i api/openapi/model-registry.yaml -g go -o internal/model/openapi --package-name openapi \ + --ignore-file-override ./.openapi-generator-ignore --additional-properties=isGoSubmodule=true,enumClassPrefix=true,useOneOfDiscriminatorLookup=true + gofmt -w internal/model/openapi + .PHONY: vet vet: go vet ./... .PHONY: clean clean: - rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/converter.go + rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/converter.go internal/model/openapi bin/go-enum: GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 @@ -52,8 +77,26 @@ bin/golangci-lint: bin/goverter: GOBIN=$(PROJECT_PATH)/bin go install github.com/jmattheis/goverter/cmd/goverter@v0.18.0 +OPENAPI_GENERATOR ?= ${PROJECT_BIN}/openapi-generator-cli +NPM ?= "$(shell which npm)" +bin/openapi-generator-cli: +ifeq (, $(shell which ${NPM} 2> /dev/null)) + @echo "npm is not available please install it to be able to install openapi-generator" + exit 1 +endif +ifeq (, $(shell which ${PROJECT_BIN}/openapi-generator-cli 2> /dev/null)) + @{ \ + set -e ;\ + mkdir -p ${PROJECT_BIN} ;\ + mkdir -p ${PROJECT_BIN}/openapi-generator-installation ;\ + cd ${PROJECT_BIN} ;\ + ${NPM} install -g --prefix ${PROJECT_BIN}/openapi-generator-installation @openapitools/openapi-generator-cli ;\ + ln -s openapi-generator-installation/bin/openapi-generator-cli openapi-generator-cli ;\ + } +endif + .PHONY: deps -deps: bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/gqlgen bin/golangci-lint bin/goverter +deps: bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/gqlgen bin/golangci-lint bin/goverter bin/openapi-generator-cli .PHONY: vendor vendor: @@ -64,7 +107,7 @@ build: gen vet lint go build .PHONY: gen -gen: deps gen/grpc gen/graph gen/converter +gen: deps gen/grpc gen/openapi gen/graph gen/converter go generate ./... .PHONY: lint @@ -86,6 +129,10 @@ metadata.sqlite.db: run/migrate run/server: gen metadata.sqlite.db go run main.go serve --logtostderr=true +.PHONY: run/proxy +run/proxy: gen + go run main.go proxy --logtostderr=true + .PHONY: run/client run/client: gen python test/python/test_mlmetadata.py diff --git a/README.md b/README.md index fb32a5ba..d35bd4b2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ It adds other features on top of the functionality offered by the gRPC interface ## Pre-requisites: - go >= 1.19 - protoc v24.3 - [Protocol Buffers v24.3 Release](https://github.com/protocolbuffers/protobuf/releases/tag/v24.3) +- npm >= 10.2.0 - [Installing Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) +- Java >= 11.0 - python 3.9 ## Building Run the following command to build the server binary: @@ -17,6 +19,13 @@ The generated binary uses spf13 cmdline args. More information on using the serv ``` ./model-registry --help ``` +## OpenAPI Proxy Server +### Starting the OpenAPI Proxy Server +Run the following command to start the OpenAPI proxy server: +``` +make run/proxy & +``` +The proxy service implements the OpenAPI defined in [model-registry.yaml](api/openapi/model-registry.yaml) to create an Open Data Hub specific REST API that stores metadata in an ml-metadata CPP server. ## Server ### Creating/Migrating Server DB The server uses a local SQLite DB file (`metadata.sqlite.db` by default), which can be configured using the `-d` cmdline option. diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml new file mode 100644 index 00000000..a051b89c --- /dev/null +++ b/api/openapi/model-registry.yaml @@ -0,0 +1,1717 @@ +openapi: 3.0.3 +info: + title: Model Registry REST API + version: 1.0.0 + description: REST API for Model Registry to create and manage ML model metadata + license: + name: Apache 2.0 + url: 'https://www.apache.org/licenses/LICENSE-2.0' +servers: + - + url: 'https://localhost:8080' +paths: + /api/model_registry/v1alpha1/model_artifact: + summary: Path used to search for a modelartifact. + description: >- + The REST endpoint/path used to search for a `ModelArtifact` entity. This path contains a `GET` + operation to perform the find task. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelArtifactResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: findModelArtifact + summary: Get a ModelArtifact that matches search parameters. + description: Gets the details of a single instance of a `ModelArtifact` that matches search parameters. + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + /api/model_registry/v1alpha1/model_artifacts: + summary: Path used to manage the list of modelartifacts. + description: >- + The REST endpoint/path used to list and create zero or more `ModelArtifact` entities. This path + contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/ModelArtifactListResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getModelArtifacts + summary: List All ModelArtifacts + description: Gets a list of all `ModelArtifact` entities. + post: + requestBody: + description: A new `ModelArtifact` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/ModelArtifactCreate' + required: true + tags: + - ModelRegistryService + responses: + '201': + $ref: '#/components/responses/ModelArtifactResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createModelArtifact + summary: Create a ModelArtifact + description: Creates a new instance of a `ModelArtifact`. + '/api/model_registry/v1alpha1/model_artifacts/{modelartifactId}': + summary: Path used to manage a single ModelArtifact. + description: >- + The REST endpoint/path used to get, update, and delete single instances of an `ModelArtifact`. + This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and + delete tasks, respectively. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelArtifactResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getModelArtifact + summary: Get a ModelArtifact + description: Gets the details of a single instance of a `ModelArtifact`. + patch: + requestBody: + description: Updated `ModelArtifact` information. + content: + application/json: + schema: + $ref: '#/components/schemas/ModelArtifactUpdate' + required: true + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelArtifactResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: updateModelArtifact + summary: Update a ModelArtifact + description: Updates an existing `ModelArtifact`. + parameters: + - + name: modelartifactId + description: A unique identifier for a `ModelArtifact`. + schema: + type: string + in: path + required: true + /api/model_registry/v1alpha1/model_versions: + summary: Path used to manage the list of modelversions. + description: >- + The REST endpoint/path used to list and create zero or more `ModelVersion` entities. This path + contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/ModelVersionListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getModelVersions + summary: List All ModelVersions + description: Gets a list of all `ModelVersion` entities. + post: + requestBody: + description: A new `ModelVersion` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/ModelVersionCreate' + required: true + tags: + - ModelRegistryService + responses: + '201': + $ref: '#/components/responses/ModelVersionResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createModelVersion + summary: Create a ModelVersion + description: Creates a new instance of a `ModelVersion`. + '/api/model_registry/v1alpha1/model_versions/{modelversionId}': + summary: Path used to manage a single ModelVersion. + description: >- + The REST endpoint/path used to get, update, and delete single instances of an `ModelVersion`. + This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and + delete tasks, respectively. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelVersionResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getModelVersion + summary: Get a ModelVersion + description: Gets the details of a single instance of a `ModelVersion`. + patch: + requestBody: + description: Updated `ModelVersion` information. + content: + application/json: + schema: + $ref: '#/components/schemas/ModelVersion' + required: true + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelVersionResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: updateModelVersion + summary: Update a ModelVersion + description: Updates an existing `ModelVersion`. + parameters: + - + name: modelversionId + description: A unique identifier for a `ModelVersion`. + schema: + type: string + in: path + required: true + /api/model_registry/v1alpha1/registered_model: + summary: Path used to search for a registeredmodel. + description: >- + The REST endpoint/path used to search for a `RegisteredModel` entity. This path contains a `GET` + operation to perform the find task. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/RegisteredModelResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: findRegisteredModel + summary: Get a RegisteredModel that matches search parameters. + description: Gets the details of a single instance of a `RegisteredModel` that matches search parameters. + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + /api/model_registry/v1alpha1/registered_models: + summary: Path used to manage the list of registeredmodels. + description: >- + The REST endpoint/path used to list and create zero or more `RegisteredModel` entities. This path + contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/RegisteredModelListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getRegisteredModels + summary: List All RegisteredModels + description: Gets a list of all `RegisteredModel` entities. + post: + requestBody: + description: A new `RegisteredModel` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/RegisteredModelCreate' + required: true + tags: + - ModelRegistryService + responses: + '201': + $ref: '#/components/responses/RegisteredModelResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createRegisteredModel + summary: Create a RegisteredModel + description: Creates a new instance of a `RegisteredModel`. + '/api/model_registry/v1alpha1/registered_models/{registeredmodelId}': + summary: Path used to manage a single RegisteredModel. + description: >- + The REST endpoint/path used to get, update, and delete single instances of an `RegisteredModel`. + This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and + delete tasks, respectively. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/RegisteredModelResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getRegisteredModel + summary: Get a RegisteredModel + description: Gets the details of a single instance of a `RegisteredModel`. + patch: + requestBody: + description: Updated `RegisteredModel` information. + content: + application/json: + schema: + $ref: '#/components/schemas/RegisteredModelUpdate' + required: true + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/RegisteredModelResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: updateRegisteredModel + summary: Update a RegisteredModel + description: Updates an existing `RegisteredModel`. + parameters: + - + name: registeredmodelId + description: A unique identifier for a `RegisteredModel`. + schema: + type: string + in: path + required: true + /api/model_registry/v1alpha1/model_version: + summary: Path used to search for a modelversion. + description: >- + The REST endpoint/path used to search for a `ModelVersion` entity. This path contains a `GET` + operation to perform the find task. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelVersionResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: findModelVersion + summary: Get a ModelVersion that matches search parameters. + description: Gets the details of a single instance of a `ModelVersion` that matches search parameters. + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + '/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts': + summary: Path used to manage the list of artifacts for a modelversion. + description: >- + The REST endpoint/path used to list and create zero or more `Artifact` entities for a + `ModelVersion`. This path contains a `GET` and `POST` operation to perform the list and create + tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/ArtifactListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getModelVersionArtifacts + summary: List All ModelVersion's artifacts + description: Gets a list of all `Artifact` entities for the `ModelVersion`. + post: + requestBody: + description: A new or existing `Artifact` to be associated with the `ModelVersion`. + content: + application/json: + schema: + $ref: '#/components/schemas/Artifact' + required: true + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ArtifactResponse' + '201': + $ref: '#/components/responses/ArtifactResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createModelVersionArtifact + summary: Create an Artifact in a ModelVersion + description: Creates a new instance of an Artifact if needed and associates it with `ModelVersion`. + parameters: + - + name: modelversionId + description: A unique identifier for a `ModelVersion`. + schema: + type: string + in: path + required: true + '/api/model_registry/v1alpha1/registered_models/{registeredmodelId}/versions': + summary: Path used to manage the list of modelversions for a registeredmodel. + description: >- + The REST endpoint/path used to list and create zero or more `ModelVersion` entities for a + `RegisteredModel`. This path contains a `GET` and `POST` operation to perform the list and create + tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/ModelVersionListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getRegisteredModelVersions + summary: List All RegisteredModel's ModelVersions + description: Gets a list of all `ModelVersion` entities for the `RegisteredModel`. + post: + requestBody: + description: A new `ModelVersion` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/ModelVersion' + required: true + tags: + - ModelRegistryService + responses: + '201': + $ref: '#/components/responses/ModelVersionResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createRegisteredModelVersion + summary: Create a ModelVersion in RegisteredModel + description: Creates a new instance of a `ModelVersion`. + parameters: + - + name: registeredmodelId + description: A unique identifier for a `RegisteredModel`. + schema: + type: string + in: path + required: true + /api/model_registry/v1alpha1/inference_service: + summary: Path used to manage an instance of inferenceservice. + description: >- + The REST endpoint/path used to list and create zero or more `InferenceService` entities. This + path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/InferenceServiceResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: findInferenceService + summary: Get an InferenceServices that matches search parameters. + description: Gets the details of a single instance of `InferenceService` that matches search parameters. + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}': + summary: Path used to manage a single InferenceService. + description: >- + The REST endpoint/path used to get, update, and delete single instances of an `InferenceService`. + This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and + delete tasks, respectively. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/InferenceServiceResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getInferenceService + summary: Get a InferenceService + description: Gets the details of a single instance of a `InferenceService`. + patch: + requestBody: + description: Updated `InferenceService` information. + content: + application/json: + schema: + $ref: '#/components/schemas/InferenceServiceUpdate' + required: true + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/InferenceServiceResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: updateInferenceService + summary: Update a InferenceService + description: Updates an existing `InferenceService`. + parameters: + - + name: inferenceserviceId + description: A unique identifier for a `InferenceService`. + schema: + type: string + in: path + required: true + /api/model_registry/v1alpha1/inference_services: + summary: Path used to manage the list of inferenceservices. + description: >- + The REST endpoint/path used to list and create zero or more `InferenceService` entities. This + path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/InferenceServiceListResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getInferenceServices + summary: List All InferenceServices + description: Gets a list of all `InferenceService` entities. + post: + requestBody: + description: A new `InferenceService` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/InferenceServiceCreate' + required: true + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/InferenceServiceResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createInferenceService + summary: Create a InferenceService + description: Creates a new instance of a `InferenceService`. + /api/model_registry/v1alpha1/serving_environment: + summary: Path used to find a servingenvironment. + description: >- + The REST endpoint/path used to search for a `ServingEnvironment` entity. This path contains a + `GET` operation to perform the find task. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ServingEnvironmentResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: findServingEnvironment + summary: Find ServingEnvironment + description: Finds a `ServingEnvironment` entity that matches query parameters. + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + /api/model_registry/v1alpha1/serving_environments: + summary: Path used to manage the list of servingenvironments. + description: >- + The REST endpoint/path used to list and create zero or more `ServingEnvironment` entities. This + path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/ServingEnvironmentListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getServingEnvironments + summary: List All ServingEnvironments + description: Gets a list of all `ServingEnvironment` entities. + post: + requestBody: + description: A new `ServingEnvironment` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/ServingEnvironmentCreate' + required: true + tags: + - ModelRegistryService + responses: + '201': + $ref: '#/components/responses/ServingEnvironmentResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createServingEnvironment + summary: Create a ServingEnvironment + description: Creates a new instance of a `ServingEnvironment`. + '/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}': + summary: Path used to manage a single ServingEnvironment. + description: >- + The REST endpoint/path used to get, update, and delete single instances of an + `ServingEnvironment`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform + the get, update, and delete tasks, respectively. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ServingEnvironmentResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getServingEnvironment + summary: Get a ServingEnvironment + description: Gets the details of a single instance of a `ServingEnvironment`. + patch: + requestBody: + description: Updated `ServingEnvironment` information. + content: + application/json: + schema: + $ref: '#/components/schemas/ServingEnvironmentUpdate' + required: true + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ServingEnvironmentResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: updateServingEnvironment + summary: Update a ServingEnvironment + description: Updates an existing `ServingEnvironment`. + parameters: + - + name: servingenvironmentId + description: A unique identifier for a `ServingEnvironment`. + schema: + type: string + in: path + required: true + '/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}/inference_services': + summary: Path used to manage the list of `InferenceServices` for a `ServingEnvironment`. + description: >- + The REST endpoint/path used to list and create zero or more `InferenceService` entities for a + `ServingEnvironment`. This path contains a `GET` and `POST` operation to perform the list and + create tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/InferenceServiceListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getEnvironmentInferenceServices + summary: List All ServingEnvironment's InferenceServices + description: Gets a list of all `InferenceService` entities for the `ServingEnvironment`. + post: + requestBody: + description: A new `InferenceService` to be created. + content: + application/json: + schema: + $ref: '#/components/schemas/InferenceServiceCreate' + required: true + tags: + - ModelRegistryService + responses: + '201': + $ref: '#/components/responses/InferenceServiceResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createEnvironmentInferenceService + summary: Create a InferenceService in ServingEnvironment + description: Creates a new instance of a `InferenceService`. + parameters: + - + name: servingenvironmentId + description: A unique identifier for a `ServingEnvironment`. + schema: + type: string + in: path + required: true + '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/serves': + summary: Path used to manage the list of `ServeModels` for a `InferenceService`. + description: >- + The REST endpoint/path used to list and create zero or more `ServeModel` entities for a + `InferenceService`. This path contains a `GET` and `POST` operation to perform the list and + create tasks, respectively. + get: + tags: + - ModelRegistryService + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + - + $ref: '#/components/parameters/pageSize' + - + $ref: '#/components/parameters/orderBy' + - + $ref: '#/components/parameters/sortOrder' + - + $ref: '#/components/parameters/nextPageToken' + responses: + '200': + $ref: '#/components/responses/ServeModelListResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getInferenceServiceServes + summary: List All InferenceService's ServeModel actions + description: Gets a list of all `ServeModel` entities for the `InferenceService`. + post: + requestBody: + description: A new `ServeModel` to be associated with the `InferenceService`. + content: + application/json: + schema: + $ref: '#/components/schemas/ServeModelCreate' + required: true + tags: + - ModelRegistryService + responses: + '201': + $ref: '#/components/responses/ServeModelResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: createInferenceServiceServe + summary: Create a ServeModel action in a InferenceService + description: Creates a new instance of a `ServeModel` associated with `InferenceService`. + parameters: + - + name: inferenceserviceId + description: A unique identifier for a `InferenceService`. + schema: + type: string + in: path + required: true + '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/model': + summary: Path used to manage a `RegisteredModel` associated with an `InferenceService`. + description: >- + The REST endpoint/path used to list the `RegisteredModel` entity for an `InferenceService`. This + path contains a `GET` operation to perform the get task. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/RegisteredModelResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getInferenceServiceModel + summary: Get InferenceService's RegisteredModel + description: Gets the `RegisteredModel` entity for the `InferenceService`. + parameters: + - + name: inferenceserviceId + description: A unique identifier for a `InferenceService`. + schema: + type: string + in: path + required: true + '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/version': + summary: Path used to get the current `ModelVersion` associated with an `InferenceService`. + description: >- + The REST endpoint/path used to get the current `ModelVersion` entity for a `InferenceService`. + This path contains a `GET` operation to perform the get task. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelVersionResponse' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: getInferenceServiceVersion + summary: Get InferenceService's ModelVersion + description: Gets the `ModelVersion` entity for the `InferenceService`. + parameters: + - + name: inferenceserviceId + description: A unique identifier for a `InferenceService`. + schema: + type: string + in: path + required: true +components: + schemas: + ArtifactState: + description: |4- + - PENDING: A state indicating that the artifact may exist. + - LIVE: A state indicating that the artifact should exist, unless something + external to the system deletes it. + - MARKED_FOR_DELETION: A state indicating that the artifact should be deleted. + - DELETED: A state indicating that the artifact has been deleted. + - ABANDONED: A state indicating that the artifact has been abandoned, which may be + due to a failed or cancelled execution. + - REFERENCE: A state indicating that the artifact is a reference artifact. At + execution start time, the orchestrator produces an output artifact for + each output key with state PENDING. However, for an intermediate + artifact, this first artifact's state will be REFERENCE. Intermediate + artifacts emitted during a component's execution will copy the REFERENCE + artifact's attributes. At the end of an execution, the artifact state + should remain REFERENCE instead of being changed to LIVE. + + See also: ml-metadata Artifact.State + default: UNKNOWN + enum: + - UNKNOWN + - PENDING + - LIVE + - MARKED_FOR_DELETION + - DELETED + - ABANDONED + - REFERENCE + type: string + ExecutionState: + description: |- + The state of the Execution. The state transitions are + NEW -> RUNNING -> COMPLETE | CACHED | FAILED | CANCELED + CACHED means the execution is skipped due to cached results. + CANCELED means the execution is skipped due to precondition not met. It is + different from CACHED in that a CANCELED execution will not have any event + associated with it. It is different from FAILED in that there is no + unexpected error happened and it is regarded as a normal state. + + See also: ml-metadata Execution.State + default: UNKNOWN + enum: + - UNKNOWN + - NEW + - RUNNING + - COMPLETE + - FAILED + - CACHED + - CANCELED + type: string + ModelArtifact: + description: An ML model artifact. + type: object + allOf: + - + $ref: '#/components/schemas/BaseArtifact' + - + $ref: '#/components/schemas/ModelArtifactCreate' + RegisteredModel: + description: A registered model in model registry. A registered model has ModelVersion children. + allOf: + - + $ref: '#/components/schemas/BaseResource' + - + type: object + - + $ref: '#/components/schemas/RegisteredModelCreate' + ModelVersionList: + description: List of ModelVersion entities. + type: object + allOf: + - + type: object + properties: + items: + description: Array of `ModelVersion` entities. + type: array + items: + $ref: '#/components/schemas/ModelVersion' + - + $ref: '#/components/schemas/BaseResourceList' + ModelArtifactList: + description: List of ModelArtifact entities. + type: object + allOf: + - + type: object + properties: + items: + description: Array of `ModelArtifact` entities. + type: array + items: + $ref: '#/components/schemas/ModelArtifact' + - + $ref: '#/components/schemas/BaseResourceList' + RegisteredModelCreate: + description: A registered model in model registry. A registered model has ModelVersion children. + allOf: + - + type: object + - + $ref: '#/components/schemas/BaseResourceCreate' + - + $ref: '#/components/schemas/RegisteredModelUpdate' + RegisteredModelUpdate: + description: A registered model in model registry. A registered model has ModelVersion children. + allOf: + - + $ref: '#/components/schemas/BaseResourceUpdate' + ModelVersion: + description: Represents a ModelVersion belonging to a RegisteredModel. + allOf: + - + $ref: '#/components/schemas/ModelVersionCreate' + - + $ref: '#/components/schemas/BaseResource' + ModelVersionCreate: + description: Represents a ModelVersion belonging to a RegisteredModel. + required: + - registeredModelID + allOf: + - + $ref: '#/components/schemas/BaseResourceCreate' + - + $ref: '#/components/schemas/ModelVersionUpdate' + properties: + registeredModelID: + description: ID of the `RegisteredModel` to which this version belongs. + type: string + ModelVersionUpdate: + description: Represents a ModelVersion belonging to a RegisteredModel. + allOf: + - + $ref: '#/components/schemas/BaseResourceUpdate' + BaseArtifactCreate: + allOf: + - + $ref: '#/components/schemas/BaseArtifactUpdate' + - + $ref: '#/components/schemas/BaseResourceCreate' + BaseArtifactUpdate: + allOf: + - + $ref: '#/components/schemas/BaseResourceUpdate' + - + type: object + properties: + uri: + description: |- + The uniform resource identifier of the physical artifact. + May be empty if there is no physical artifact. + type: string + state: + $ref: '#/components/schemas/ArtifactState' + BaseExecution: + allOf: + - + $ref: '#/components/schemas/BaseExecutionCreate' + - + type: object + - + $ref: '#/components/schemas/BaseResource' + BaseExecutionCreate: + allOf: + - + $ref: '#/components/schemas/BaseExecutionUpdate' + - + type: object + - + $ref: '#/components/schemas/BaseResourceCreate' + BaseExecutionUpdate: + type: object + allOf: + - + type: object + properties: + lastKnownState: + $ref: '#/components/schemas/ExecutionState' + - + $ref: '#/components/schemas/BaseResourceUpdate' + MetadataValue: + oneOf: + - + type: object + properties: + int_value: + format: int64 + type: string + - + type: object + properties: + double_value: + format: double + type: number + - + type: object + properties: + string_value: + type: string + - + type: object + properties: + struct_value: + description: Base64 encoded bytes for struct value + type: string + - + type: object + properties: + type: + description: url describing proto value + type: string + proto_value: + description: Base64 encoded bytes for proto value + type: string + - + type: object + properties: + bool_value: + type: boolean + description: A value in properties. + BaseResource: + allOf: + - + $ref: '#/components/schemas/BaseResourceCreate' + - + type: object + properties: + id: + format: int64 + description: Output only. The unique server generated id of the resource. + type: string + readOnly: true + createTimeSinceEpoch: + format: int64 + description: Output only. Create time of the resource in millisecond since epoch. + type: string + readOnly: true + lastUpdateTimeSinceEpoch: + format: int64 + description: |- + Output only. Last update time of the resource since epoch in millisecond + since epoch. + type: string + readOnly: true + BaseResourceCreate: + allOf: + - + $ref: '#/components/schemas/BaseResourceUpdate' + - + type: object + properties: + name: + description: |- + The client provided name of the artifact. This field is optional. If set, + it must be unique among all the artifacts of the same artifact type within + a database instance and cannot be changed once set. + type: string + BaseResourceUpdate: + type: object + properties: + customProperties: + description: User provided custom properties which are not defined by its type. + type: object + additionalProperties: + $ref: '#/components/schemas/MetadataValue' + externalID: + description: |- + The external id that come from the clients’ system. This field is optional. + If set, it must be unique among all resources within a database instance. + type: string + BaseResourceList: + required: + - nextPageToken + - pageSize + - size + type: object + properties: + nextPageToken: + description: Token to use to retrieve next page of results. + type: string + pageSize: + format: int32 + description: Maximum number of resources to return in the result. + type: integer + size: + format: int32 + description: Number of items in result list. + type: integer + ArtifactList: + description: A list of Artifact entities. + type: object + allOf: + - + type: object + properties: + items: + description: Array of `Artifact` entities. + type: array + items: + $ref: '#/components/schemas/Artifact' + - + $ref: '#/components/schemas/BaseResourceList' + ModelArtifactUpdate: + description: An ML model artifact. + allOf: + - + $ref: '#/components/schemas/BaseArtifactUpdate' + - + type: object + properties: + modelFormatName: + description: Name of the model format. + type: string + runtime: + description: Model runtime. + type: string + storageKey: + description: Storage secret name. + type: string + storagePath: + description: Path for model in storage provided by `storageKey`. + type: string + modelFormatVersion: + description: Version of the model format. + type: string + serviceAccountName: + description: Name of the service account with storage secret. + type: string + ModelArtifactCreate: + description: An ML model artifact. + type: object + allOf: + - + $ref: '#/components/schemas/BaseArtifactCreate' + - + $ref: '#/components/schemas/ModelArtifactUpdate' + Error: + description: Error code and message. + required: + - code + - message + type: object + properties: + code: + description: Error code + type: string + message: + description: Error message + type: string + SortOrder: + description: Supported sort direction for ordering result entities. + enum: + - ASC + - DESC + type: string + OrderByField: + description: Supported fields for ordering result entities. + enum: + - CREATE_TIME + - LAST_UPDATE_TIME + - ID + type: string + Artifact: + oneOf: + - + $ref: '#/components/schemas/ModelArtifact' + discriminator: + propertyName: artifactType + mapping: + model-artifact: '#/components/schemas/ModelArtifact' + description: A metadata Artifact Entity. + BaseArtifact: + allOf: + - + $ref: '#/components/schemas/BaseArtifactCreate' + - + $ref: '#/components/schemas/BaseResource' + - + required: + - artifactType + type: object + properties: + artifactType: + type: string + ServingEnvironmentList: + description: List of ServingEnvironments. + type: object + allOf: + - + type: object + properties: + items: + description: '' + type: array + items: + $ref: '#/components/schemas/ServingEnvironment' + readOnly: false + - + $ref: '#/components/schemas/BaseResourceList' + RegisteredModelList: + description: List of RegisteredModels. + type: object + allOf: + - + type: object + properties: + items: + description: '' + type: array + items: + $ref: '#/components/schemas/RegisteredModel' + readOnly: false + - + $ref: '#/components/schemas/BaseResourceList' + ServingEnvironment: + description: A Model Serving environment for serving `RegisteredModels`. + allOf: + - + $ref: '#/components/schemas/BaseResource' + - + type: object + - + $ref: '#/components/schemas/ServingEnvironmentCreate' + ServingEnvironmentUpdate: + description: A Model Serving environment for serving `RegisteredModels`. + allOf: + - + $ref: '#/components/schemas/BaseResourceUpdate' + ServingEnvironmentCreate: + description: A Model Serving environment for serving `RegisteredModels`. + allOf: + - + type: object + - + $ref: '#/components/schemas/BaseResourceCreate' + - + $ref: '#/components/schemas/ServingEnvironmentUpdate' + InferenceService: + description: >- + An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` + from a `RegisteredModel` created by Model Serving. + allOf: + - + $ref: '#/components/schemas/BaseResource' + - + $ref: '#/components/schemas/InferenceServiceCreate' + InferenceServiceList: + description: List of InferenceServices. + type: object + allOf: + - + type: object + properties: + items: + description: '' + type: array + items: + $ref: '#/components/schemas/InferenceService' + readOnly: false + - + $ref: '#/components/schemas/BaseResourceList' + ServeModelList: + description: List of ServeModel entities. + type: object + allOf: + - + type: object + properties: + items: + description: Array of `ModelArtifact` entities. + type: array + items: + $ref: '#/components/schemas/ServeModel' + - + $ref: '#/components/schemas/BaseResourceList' + ServeModel: + description: An ML model serving action. + type: object + allOf: + - + $ref: '#/components/schemas/BaseExecution' + - + $ref: '#/components/schemas/ServeModelCreate' + ServeModelUpdate: + description: An ML model serving action. + allOf: + - + $ref: '#/components/schemas/BaseExecutionUpdate' + ServeModelCreate: + description: An ML model serving action. + allOf: + - + $ref: '#/components/schemas/BaseExecutionCreate' + - + $ref: '#/components/schemas/ServeModelUpdate' + - + required: + - modelVersionId + type: object + properties: + modelVersionId: + description: ID of the `ModelVersion` that was served in `InferenceService`. + type: string + InferenceServiceUpdate: + description: >- + An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` + from a `RegisteredModel` created by Model Serving. + allOf: + - + $ref: '#/components/schemas/BaseResourceUpdate' + - + type: object + properties: + modelVersionId: + description: >- + ID of the `ModelVersion` to serve. If it's unspecified, then the latest + `ModelVersion` by creation order will be served. + type: string + InferenceServiceCreate: + description: >- + An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` + from a `RegisteredModel` created by Model Serving. + allOf: + - + $ref: '#/components/schemas/BaseResourceCreate' + - + $ref: '#/components/schemas/InferenceServiceUpdate' + - + required: + - registeredModelId + - servingEnvironmentId + type: object + properties: + registeredModelId: + description: ID of the `RegisteredModel` to serve. + type: string + servingEnvironmentId: + description: ID of the parent `ServingEnvironment` for this `InferenceService` entity. + type: string + responses: + NotFound: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: The specified resource was not found + BadRequest: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Bad Request parameters + Unauthorized: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unauthorized + InternalServerError: + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + description: Unexpected internal server error + ModelArtifactListResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ModelArtifactList' + description: A response containing a list of ModelArtifact entities. + ModelArtifactResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ModelArtifact' + description: A response containing a `ModelArtifact` entity. + ModelVersionListResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ModelVersionList' + description: A response containing a list of `ModelVersion` entities. + ModelVersionResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ModelVersion' + description: A response containing a `ModelVersion` entity. + RegisteredModelListResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisteredModelList' + description: A response containing a list of `RegisteredModel` entities. + RegisteredModelResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisteredModel' + description: A response containing a `RegisteredModel` entity. + ArtifactResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/Artifact' + description: A response containing an `Artifact` entity. + ArtifactListResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ArtifactList' + description: A response containing a list of `Artifact` entities. + ServingEnvironmentListResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ServingEnvironmentList' + description: A response containing a list of `ServingEnvironment` entities. + ServingEnvironmentResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ServingEnvironment' + description: A response containing a `ServingEnvironment` entity. + InferenceServiceListResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/InferenceServiceList' + description: A response containing a list of `InferenceService` entities. + InferenceServiceResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/InferenceService' + description: A response containing a `InferenceService` entity. + ServeModelListResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ServeModelList' + description: A response containing a list of `ServeModel` entities. + ServeModelResponse: + content: + application/json: + schema: + $ref: '#/components/schemas/ServeModel' + description: A response containing a `ServeModel` entity. + parameters: + id: + name: id + description: The ID of resource. + schema: + type: string + in: path + required: true + name: + examples: + name: + value: entity-name + name: name + description: Name of entity to search. + schema: + type: string + in: query + required: false + externalID: + examples: + externalID: + value: '10' + name: externalID + description: External ID of entity to search. + schema: + type: string + in: query + required: false + pageSize: + examples: + pageSize: + value: '100' + name: pageSize + description: Number of entities in each page. + schema: + type: string + in: query + required: false + nextPageToken: + examples: + nextPageToken: + value: IkhlbGxvLCB3b3JsZC4i + name: nextPageToken + description: Token to use to retrieve next page of results. + schema: + type: string + in: query + required: false + orderBy: + style: form + explode: true + examples: + orderBy: + value: ID + name: orderBy + description: Specifies the order by criteria for listing entities. + schema: + $ref: '#/components/schemas/OrderByField' + in: query + required: false + sortOrder: + style: form + explode: true + examples: + sortOrder: + value: DESC + name: sortOrder + description: 'Specifies the sort order for listing entities, defaults to ASC.' + schema: + $ref: '#/components/schemas/SortOrder' + in: query + required: false + securitySchemes: + Bearer: + scheme: bearer + bearerFormat: JWT + type: http + description: Bearer JWT scheme +security: + - + Bearer: [] +tags: + - + name: ModelRegistryService + description: Model Registry Service REST API diff --git a/api/openapi/modelregistry.yml b/api/openapi/modelregistry.yml deleted file mode 100644 index 62f2e4ac..00000000 --- a/api/openapi/modelregistry.yml +++ /dev/null @@ -1,369 +0,0 @@ -openapi: 3.0.2 -info: - title: Model Registry API - version: 1.0.0 - description: 'See also https://github.com/opendatahub-io/model-registry/issues/44#issue-1919724627' -paths: - /environments: - summary: Path used to manage the list of environments. - description: >- - The REST endpoint/path used to list and create zero or more `Environment` entities. This path - contains a `GET` and `POST` operation to perform the list and create tasks, respectively. - get: - responses: - '200': - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Environment' - description: Successful response - returns an array of `Environment` entities. - operationId: getEnvironments - summary: List All Environments - description: Gets a list of all `Environment` entities. - post: - requestBody: - description: A new `Environment` to be created. - content: - application/json: - schema: - $ref: '#/components/schemas/Environment' - required: true - responses: - '201': - description: Successful response. - operationId: createEnvironment - summary: Create a Environment - description: Creates a new instance of a `Environment`. - delete: - parameters: - - - name: name - description: '' - schema: {} - in: query - responses: - '200': - description: Successfully deleted `Environment` having `name`. - summary: Delete an Environment - description: 'Placed here only to avoid subpaths, can be re-drawn.' - /search: - description: |- - TBD: We feel this might be redundant with `models/` and `models/{name}`. - We suggest instead to: - 1. avoid usage of Query param (that might "explode" as search grows) - 2. provide search criteria in the body - get: - responses: - '200': - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/RegisteredModel' - description: Get all `RegisteredModel`s matching the supplied criteria. - summary: Search models - parameters: - - - name: name - description: '' - schema: - type: string - in: query - - - name: id - description: '' - schema: - type: string - in: query - - - name: tag - description: '' - schema: - type: string - in: query - - - name: label - description: '' - schema: - type: string - in: query - /models: - get: - responses: - '200': - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/RegisteredModel' - description: List all - summary: List all Models - description: List all `RegisteredModel` and belonging `VersionedModel`(s). - post: - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/VersionedModel' - required: true - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/VersionedModel' - description: Successfully created a `VersionedModel` for a Registered model. - summary: Assign a version to a registered model - description: |- - If a `RegisteredModel` for `model_name` already exists, this `VersionedModel` - will be assigned to it, else a new `RegisteredModel` will be created. - If a `model_name` is not provided, a random one will be used. - - The `id` is generated in the backend by the registry. - It could be implemented as a progressive number, to be decided. - The `id`s are unique within a RegisteredModel. - - The `version` is a user-provided symbolic name, for instance semantic versioning - The `version` if provided must be unique and non-already-existing within a - RegisterdModel and must not be the same as any of the `id`s. - '/models/{name}/versions/{version}': - get: - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/VersionedModel' - description: get `VersionedModel` for model name and version - summary: Get Version details - delete: - responses: - '200': - description: Successfully archive a `VersionedModel`. - summary: Archive a VersionedModel - description: 'This does NOT delete any `VersionedModel`, but archives and deprecate it.' - patch: - requestBody: - description: 'The `uri`, `id`, `version` and other non-updatable fields will be ignored.' - content: - application/json: - schema: - $ref: '#/components/schemas/VersionedModel' - required: true - responses: - '200': - description: Successfully upated a `VersionedModel` in the updatable and provided fields. - description: |- - Updates a `VersionedModel` only for the updatable fields, such as label, tags, - description. - - Some fields will not be updated even if supplied, such as `model_uri`, `id`, - `version`. - parameters: - - - name: name - schema: - type: string - in: path - required: true - - - name: version - schema: - type: string - in: path - required: true - '/models/{name}': - get: - responses: - '200': - content: - application/json: - schema: - $ref: '#/components/schemas/RegisteredModel' - description: Retrieves the `RegisteredModel`. - summary: Return a given RegisteredModel - post: - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/VersionedModel' - responses: - '200': - description: Successfully registered a versionedmodel under a registered model. - summary: Register a VersionedModel under a given name - description: |- - TBD: this as a potential alternative or complementary of `/models` POST - where the model's name is provided as a Path param instead. - parameters: - - - name: name - schema: - type: string - in: path - required: true -components: - schemas: - Environment: - title: Root Type for Environment - description: '' - type: object - properties: - name: - type: string - uri: - type: string - example: - name: My Environment - uri: 'http://localhost:8080' - RegisteredModel: - title: Root Type for RegisteredModel - description: '' - type: object - properties: - name: - type: string - labels: - type: array - items: - type: string - versions: - type: array - items: - $ref: '#/components/schemas/VersionedModel' - example: - name: my ML pricing model - labels: - - tutorial - - linreg - versions: - - - model_name: my ML pricing model - id: ae123-78932-64893 - version: v1 - model_uri: 's3://89492-46893-54692' - tags: - - Staging - labels: - - tutorial - - linreg - environments: - - - name: My Environment - uri: 'http://localhost:8080' - created date: '20231002T12:34:56' - updated date: '20231002T12:34:56' - author: 'John Doe, data scientist' - origin: 'dsp://123' - metadata: - accuracy: 99 - artifacts: - - - name: dataset - type: csv - uri: 's3://67489-46393-63469' - metadata: - authority: US Census - VersionedModel: - title: Root Type for VersionedModel - description: '' - required: - - model_uri - type: object - properties: - id: - type: string - version: - type: string - tags: - type: array - items: - type: string - labels: - type: array - items: - type: string - environments: - type: array - items: - $ref: '#/components/schemas/Environment' - created date: - format: date-time - type: string - updated date: - format: date-time - type: string - model_name: - type: string - author: - description: '' - type: string - example: '"John Doe, data scientist"' - metadata: - description: '' - type: object - model_uri: - description: '' - type: string - artifacts: - description: '' - type: array - items: - $ref: '#/components/schemas/Artifact' - origin: - description: 'For instance, the DSP id which realized the model' - type: string - example: - model_name: my ML pricing model - id: ae123-78932-64893 - version: v1 - model_uri: 's3://89492-46893-54692' - tags: - - Staging - labels: - - tutorial - - linreg - environments: - - - name: My Environment - uri: 'http://localhost:8080' - created date: '20231002T12:34:56' - updated date: '20231002T12:34:56' - author: 'John Doe, data scientist' - origin: 'dsp://123' - metadata: - accuracy: 99 - artifacts: - - - name: dataset - type: csv - uri: 's3://67489-46393-63469' - metadata: - authority: US Census - Artifact: - title: Root Type for Artifact - description: '' - type: object - properties: - type: - type: string - uri: - type: string - metadata: - type: object - properties: - authority: - type: string - name: - description: '' - type: string - example: - name: dataset - type: csv - uri: 's3://67489-46393-63469' - metadata: - authority: US Census diff --git a/cmd/proxy.go b/cmd/proxy.go new file mode 100644 index 00000000..167ded09 --- /dev/null +++ b/cmd/proxy.go @@ -0,0 +1,50 @@ +package cmd + +import ( + "fmt" + "github.com/golang/glog" + "github.com/opendatahub-io/model-registry/internal/server/openapi" + "github.com/spf13/cobra" + "log" + "net/http" +) + +var ( + // proxyCmd represents the proxy command + proxyCmd = &cobra.Command{ + Use: "proxy", + Short: "Starts the ml-metadata go OpenAPI proxy", + Long: `This command launches the ml-metadata go OpenAPI proxy server. + +The server connects to a mlmd CPP server. It supports options to customize the +hostname and port where it listens.'`, + RunE: runProxyServer, + } +) + +func runProxyServer(cmd *cobra.Command, args []string) error { + glog.Infof("proxy server started at %s:%v", cfg.Hostname, cfg.Port) + + ModelRegistryServiceAPIService := openapi.NewModelRegistryServiceAPIService() + ModelRegistryServiceAPIController := openapi.NewModelRegistryServiceAPIController(ModelRegistryServiceAPIService) + + router := openapi.NewRouter(ModelRegistryServiceAPIController) + + log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", cfg.Hostname, cfg.Port), router)) + return nil +} + +func init() { + rootCmd.AddCommand(proxyCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // proxyCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + proxyCmd.Flags().StringVarP(&cfg.Hostname, "hostname", "n", cfg.Hostname, "Proxy server listen hostname") + proxyCmd.Flags().IntVarP(&cfg.Port, "port", "p", cfg.Port, "Proxy server listen port") +} diff --git a/go.mod b/go.mod index 42b125ac..96c0acaa 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.19 require ( github.com/99designs/gqlgen v0.17.36 + github.com/go-chi/chi/v5 v5.0.10 github.com/golang/glog v1.1.0 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 github.com/searKing/golang/tools/go-enum v1.2.97 diff --git a/go.sum b/go.sum index df978020..938301e1 100644 --- a/go.sum +++ b/go.sum @@ -70,6 +70,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= +github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= diff --git a/internal/model/openapi/.openapi-generator/FILES b/internal/model/openapi/.openapi-generator/FILES new file mode 100644 index 00000000..0efba780 --- /dev/null +++ b/internal/model/openapi/.openapi-generator/FILES @@ -0,0 +1,53 @@ +api_model_registry_service.go +client.go +configuration.go +model_artifact.go +model_artifact_list.go +model_artifact_state.go +model_base_artifact.go +model_base_artifact_create.go +model_base_artifact_update.go +model_base_execution.go +model_base_execution_create.go +model_base_execution_update.go +model_base_resource.go +model_base_resource_create.go +model_base_resource_list.go +model_base_resource_update.go +model_error.go +model_execution_state.go +model_inference_service.go +model_inference_service_create.go +model_inference_service_list.go +model_inference_service_update.go +model_metadata_value.go +model_metadata_value_one_of.go +model_metadata_value_one_of_1.go +model_metadata_value_one_of_2.go +model_metadata_value_one_of_3.go +model_metadata_value_one_of_4.go +model_metadata_value_one_of_5.go +model_model_artifact.go +model_model_artifact_create.go +model_model_artifact_list.go +model_model_artifact_update.go +model_model_version.go +model_model_version_create.go +model_model_version_list.go +model_model_version_update.go +model_order_by_field.go +model_registered_model.go +model_registered_model_create.go +model_registered_model_list.go +model_registered_model_update.go +model_serve_model.go +model_serve_model_create.go +model_serve_model_list.go +model_serve_model_update.go +model_serving_environment.go +model_serving_environment_create.go +model_serving_environment_list.go +model_serving_environment_update.go +model_sort_order.go +response.go +utils.go diff --git a/internal/model/openapi/.openapi-generator/VERSION b/internal/model/openapi/.openapi-generator/VERSION new file mode 100644 index 00000000..73a86b19 --- /dev/null +++ b/internal/model/openapi/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.0.1 \ No newline at end of file diff --git a/internal/model/openapi/api_model_registry_service.go b/internal/model/openapi/api_model_registry_service.go new file mode 100644 index 00000000..f23c4238 --- /dev/null +++ b/internal/model/openapi/api_model_registry_service.go @@ -0,0 +1,5552 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + "strings" +) + +// ModelRegistryServiceAPIService ModelRegistryServiceAPI service +type ModelRegistryServiceAPIService service + +type ApiCreateEnvironmentInferenceServiceRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + servingenvironmentId string + inferenceServiceCreate *InferenceServiceCreate +} + +// A new `InferenceService` to be created. +func (r ApiCreateEnvironmentInferenceServiceRequest) InferenceServiceCreate(inferenceServiceCreate InferenceServiceCreate) ApiCreateEnvironmentInferenceServiceRequest { + r.inferenceServiceCreate = &inferenceServiceCreate + return r +} + +func (r ApiCreateEnvironmentInferenceServiceRequest) Execute() (*InferenceService, *http.Response, error) { + return r.ApiService.CreateEnvironmentInferenceServiceExecute(r) +} + +/* +CreateEnvironmentInferenceService Create a InferenceService in ServingEnvironment + +Creates a new instance of a `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param servingenvironmentId A unique identifier for a `ServingEnvironment`. + @return ApiCreateEnvironmentInferenceServiceRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateEnvironmentInferenceService(ctx context.Context, servingenvironmentId string) ApiCreateEnvironmentInferenceServiceRequest { + return ApiCreateEnvironmentInferenceServiceRequest{ + ApiService: a, + ctx: ctx, + servingenvironmentId: servingenvironmentId, + } +} + +// Execute executes the request +// +// @return InferenceService +func (a *ModelRegistryServiceAPIService) CreateEnvironmentInferenceServiceExecute(r ApiCreateEnvironmentInferenceServiceRequest) (*InferenceService, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *InferenceService + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateEnvironmentInferenceService") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}/inference_services" + localVarPath = strings.Replace(localVarPath, "{"+"servingenvironmentId"+"}", url.PathEscape(parameterValueToString(r.servingenvironmentId, "servingenvironmentId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.inferenceServiceCreate == nil { + return localVarReturnValue, nil, reportError("inferenceServiceCreate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.inferenceServiceCreate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateInferenceServiceRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + inferenceServiceCreate *InferenceServiceCreate +} + +// A new `InferenceService` to be created. +func (r ApiCreateInferenceServiceRequest) InferenceServiceCreate(inferenceServiceCreate InferenceServiceCreate) ApiCreateInferenceServiceRequest { + r.inferenceServiceCreate = &inferenceServiceCreate + return r +} + +func (r ApiCreateInferenceServiceRequest) Execute() (*InferenceService, *http.Response, error) { + return r.ApiService.CreateInferenceServiceExecute(r) +} + +/* +CreateInferenceService Create a InferenceService + +Creates a new instance of a `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateInferenceServiceRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateInferenceService(ctx context.Context) ApiCreateInferenceServiceRequest { + return ApiCreateInferenceServiceRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return InferenceService +func (a *ModelRegistryServiceAPIService) CreateInferenceServiceExecute(r ApiCreateInferenceServiceRequest) (*InferenceService, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *InferenceService + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateInferenceService") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.inferenceServiceCreate == nil { + return localVarReturnValue, nil, reportError("inferenceServiceCreate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.inferenceServiceCreate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateInferenceServiceServeRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + inferenceserviceId string + serveModelCreate *ServeModelCreate +} + +// A new `ServeModel` to be associated with the `InferenceService`. +func (r ApiCreateInferenceServiceServeRequest) ServeModelCreate(serveModelCreate ServeModelCreate) ApiCreateInferenceServiceServeRequest { + r.serveModelCreate = &serveModelCreate + return r +} + +func (r ApiCreateInferenceServiceServeRequest) Execute() (*ServeModel, *http.Response, error) { + return r.ApiService.CreateInferenceServiceServeExecute(r) +} + +/* +CreateInferenceServiceServe Create a ServeModel action in a InferenceService + +Creates a new instance of a `ServeModel` associated with `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param inferenceserviceId A unique identifier for a `InferenceService`. + @return ApiCreateInferenceServiceServeRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateInferenceServiceServe(ctx context.Context, inferenceserviceId string) ApiCreateInferenceServiceServeRequest { + return ApiCreateInferenceServiceServeRequest{ + ApiService: a, + ctx: ctx, + inferenceserviceId: inferenceserviceId, + } +} + +// Execute executes the request +// +// @return ServeModel +func (a *ModelRegistryServiceAPIService) CreateInferenceServiceServeExecute(r ApiCreateInferenceServiceServeRequest) (*ServeModel, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServeModel + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateInferenceServiceServe") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/serves" + localVarPath = strings.Replace(localVarPath, "{"+"inferenceserviceId"+"}", url.PathEscape(parameterValueToString(r.inferenceserviceId, "inferenceserviceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.serveModelCreate == nil { + return localVarReturnValue, nil, reportError("serveModelCreate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.serveModelCreate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateModelArtifactRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelArtifactCreate *ModelArtifactCreate +} + +// A new `ModelArtifact` to be created. +func (r ApiCreateModelArtifactRequest) ModelArtifactCreate(modelArtifactCreate ModelArtifactCreate) ApiCreateModelArtifactRequest { + r.modelArtifactCreate = &modelArtifactCreate + return r +} + +func (r ApiCreateModelArtifactRequest) Execute() (*ModelArtifact, *http.Response, error) { + return r.ApiService.CreateModelArtifactExecute(r) +} + +/* +CreateModelArtifact Create a ModelArtifact + +Creates a new instance of a `ModelArtifact`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateModelArtifactRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateModelArtifact(ctx context.Context) ApiCreateModelArtifactRequest { + return ApiCreateModelArtifactRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelArtifact +func (a *ModelRegistryServiceAPIService) CreateModelArtifactExecute(r ApiCreateModelArtifactRequest) (*ModelArtifact, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelArtifact + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateModelArtifact") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_artifacts" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.modelArtifactCreate == nil { + return localVarReturnValue, nil, reportError("modelArtifactCreate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.modelArtifactCreate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateModelVersionRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelVersionCreate *ModelVersionCreate +} + +// A new `ModelVersion` to be created. +func (r ApiCreateModelVersionRequest) ModelVersionCreate(modelVersionCreate ModelVersionCreate) ApiCreateModelVersionRequest { + r.modelVersionCreate = &modelVersionCreate + return r +} + +func (r ApiCreateModelVersionRequest) Execute() (*ModelVersion, *http.Response, error) { + return r.ApiService.CreateModelVersionExecute(r) +} + +/* +CreateModelVersion Create a ModelVersion + +Creates a new instance of a `ModelVersion`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateModelVersionRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateModelVersion(ctx context.Context) ApiCreateModelVersionRequest { + return ApiCreateModelVersionRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelVersion +func (a *ModelRegistryServiceAPIService) CreateModelVersionExecute(r ApiCreateModelVersionRequest) (*ModelVersion, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersion + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateModelVersion") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_versions" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.modelVersionCreate == nil { + return localVarReturnValue, nil, reportError("modelVersionCreate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.modelVersionCreate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateModelVersionArtifactRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelversionId string + artifact *Artifact +} + +// A new or existing `Artifact` to be associated with the `ModelVersion`. +func (r ApiCreateModelVersionArtifactRequest) Artifact(artifact Artifact) ApiCreateModelVersionArtifactRequest { + r.artifact = &artifact + return r +} + +func (r ApiCreateModelVersionArtifactRequest) Execute() (*Artifact, *http.Response, error) { + return r.ApiService.CreateModelVersionArtifactExecute(r) +} + +/* +CreateModelVersionArtifact Create an Artifact in a ModelVersion + +Creates a new instance of an Artifact if needed and associates it with `ModelVersion`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param modelversionId A unique identifier for a `ModelVersion`. + @return ApiCreateModelVersionArtifactRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateModelVersionArtifact(ctx context.Context, modelversionId string) ApiCreateModelVersionArtifactRequest { + return ApiCreateModelVersionArtifactRequest{ + ApiService: a, + ctx: ctx, + modelversionId: modelversionId, + } +} + +// Execute executes the request +// +// @return Artifact +func (a *ModelRegistryServiceAPIService) CreateModelVersionArtifactExecute(r ApiCreateModelVersionArtifactRequest) (*Artifact, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Artifact + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateModelVersionArtifact") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts" + localVarPath = strings.Replace(localVarPath, "{"+"modelversionId"+"}", url.PathEscape(parameterValueToString(r.modelversionId, "modelversionId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.artifact == nil { + return localVarReturnValue, nil, reportError("artifact is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.artifact + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateRegisteredModelRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + registeredModelCreate *RegisteredModelCreate +} + +// A new `RegisteredModel` to be created. +func (r ApiCreateRegisteredModelRequest) RegisteredModelCreate(registeredModelCreate RegisteredModelCreate) ApiCreateRegisteredModelRequest { + r.registeredModelCreate = ®isteredModelCreate + return r +} + +func (r ApiCreateRegisteredModelRequest) Execute() (*RegisteredModel, *http.Response, error) { + return r.ApiService.CreateRegisteredModelExecute(r) +} + +/* +CreateRegisteredModel Create a RegisteredModel + +Creates a new instance of a `RegisteredModel`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateRegisteredModelRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateRegisteredModel(ctx context.Context) ApiCreateRegisteredModelRequest { + return ApiCreateRegisteredModelRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return RegisteredModel +func (a *ModelRegistryServiceAPIService) CreateRegisteredModelExecute(r ApiCreateRegisteredModelRequest) (*RegisteredModel, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RegisteredModel + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateRegisteredModel") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/registered_models" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.registeredModelCreate == nil { + return localVarReturnValue, nil, reportError("registeredModelCreate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.registeredModelCreate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateRegisteredModelVersionRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + registeredmodelId string + modelVersion *ModelVersion +} + +// A new `ModelVersion` to be created. +func (r ApiCreateRegisteredModelVersionRequest) ModelVersion(modelVersion ModelVersion) ApiCreateRegisteredModelVersionRequest { + r.modelVersion = &modelVersion + return r +} + +func (r ApiCreateRegisteredModelVersionRequest) Execute() (*ModelVersion, *http.Response, error) { + return r.ApiService.CreateRegisteredModelVersionExecute(r) +} + +/* +CreateRegisteredModelVersion Create a ModelVersion in RegisteredModel + +Creates a new instance of a `ModelVersion`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param registeredmodelId A unique identifier for a `RegisteredModel`. + @return ApiCreateRegisteredModelVersionRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateRegisteredModelVersion(ctx context.Context, registeredmodelId string) ApiCreateRegisteredModelVersionRequest { + return ApiCreateRegisteredModelVersionRequest{ + ApiService: a, + ctx: ctx, + registeredmodelId: registeredmodelId, + } +} + +// Execute executes the request +// +// @return ModelVersion +func (a *ModelRegistryServiceAPIService) CreateRegisteredModelVersionExecute(r ApiCreateRegisteredModelVersionRequest) (*ModelVersion, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersion + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateRegisteredModelVersion") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}/versions" + localVarPath = strings.Replace(localVarPath, "{"+"registeredmodelId"+"}", url.PathEscape(parameterValueToString(r.registeredmodelId, "registeredmodelId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.modelVersion == nil { + return localVarReturnValue, nil, reportError("modelVersion is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.modelVersion + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiCreateServingEnvironmentRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + servingEnvironmentCreate *ServingEnvironmentCreate +} + +// A new `ServingEnvironment` to be created. +func (r ApiCreateServingEnvironmentRequest) ServingEnvironmentCreate(servingEnvironmentCreate ServingEnvironmentCreate) ApiCreateServingEnvironmentRequest { + r.servingEnvironmentCreate = &servingEnvironmentCreate + return r +} + +func (r ApiCreateServingEnvironmentRequest) Execute() (*ServingEnvironment, *http.Response, error) { + return r.ApiService.CreateServingEnvironmentExecute(r) +} + +/* +CreateServingEnvironment Create a ServingEnvironment + +Creates a new instance of a `ServingEnvironment`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateServingEnvironmentRequest +*/ +func (a *ModelRegistryServiceAPIService) CreateServingEnvironment(ctx context.Context) ApiCreateServingEnvironmentRequest { + return ApiCreateServingEnvironmentRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ServingEnvironment +func (a *ModelRegistryServiceAPIService) CreateServingEnvironmentExecute(r ApiCreateServingEnvironmentRequest) (*ServingEnvironment, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServingEnvironment + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.CreateServingEnvironment") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/serving_environments" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.servingEnvironmentCreate == nil { + return localVarReturnValue, nil, reportError("servingEnvironmentCreate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.servingEnvironmentCreate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiFindInferenceServiceRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string +} + +// Name of entity to search. +func (r ApiFindInferenceServiceRequest) Name(name string) ApiFindInferenceServiceRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiFindInferenceServiceRequest) ExternalID(externalID string) ApiFindInferenceServiceRequest { + r.externalID = &externalID + return r +} + +func (r ApiFindInferenceServiceRequest) Execute() (*InferenceService, *http.Response, error) { + return r.ApiService.FindInferenceServiceExecute(r) +} + +/* +FindInferenceService Get an InferenceServices that matches search parameters. + +Gets the details of a single instance of `InferenceService` that matches search parameters. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiFindInferenceServiceRequest +*/ +func (a *ModelRegistryServiceAPIService) FindInferenceService(ctx context.Context) ApiFindInferenceServiceRequest { + return ApiFindInferenceServiceRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return InferenceService +func (a *ModelRegistryServiceAPIService) FindInferenceServiceExecute(r ApiFindInferenceServiceRequest) (*InferenceService, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *InferenceService + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.FindInferenceService") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_service" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiFindModelArtifactRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string +} + +// Name of entity to search. +func (r ApiFindModelArtifactRequest) Name(name string) ApiFindModelArtifactRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiFindModelArtifactRequest) ExternalID(externalID string) ApiFindModelArtifactRequest { + r.externalID = &externalID + return r +} + +func (r ApiFindModelArtifactRequest) Execute() (*ModelArtifact, *http.Response, error) { + return r.ApiService.FindModelArtifactExecute(r) +} + +/* +FindModelArtifact Get a ModelArtifact that matches search parameters. + +Gets the details of a single instance of a `ModelArtifact` that matches search parameters. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiFindModelArtifactRequest +*/ +func (a *ModelRegistryServiceAPIService) FindModelArtifact(ctx context.Context) ApiFindModelArtifactRequest { + return ApiFindModelArtifactRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelArtifact +func (a *ModelRegistryServiceAPIService) FindModelArtifactExecute(r ApiFindModelArtifactRequest) (*ModelArtifact, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelArtifact + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.FindModelArtifact") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_artifact" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiFindModelVersionRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string +} + +// Name of entity to search. +func (r ApiFindModelVersionRequest) Name(name string) ApiFindModelVersionRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiFindModelVersionRequest) ExternalID(externalID string) ApiFindModelVersionRequest { + r.externalID = &externalID + return r +} + +func (r ApiFindModelVersionRequest) Execute() (*ModelVersion, *http.Response, error) { + return r.ApiService.FindModelVersionExecute(r) +} + +/* +FindModelVersion Get a ModelVersion that matches search parameters. + +Gets the details of a single instance of a `ModelVersion` that matches search parameters. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiFindModelVersionRequest +*/ +func (a *ModelRegistryServiceAPIService) FindModelVersion(ctx context.Context) ApiFindModelVersionRequest { + return ApiFindModelVersionRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelVersion +func (a *ModelRegistryServiceAPIService) FindModelVersionExecute(r ApiFindModelVersionRequest) (*ModelVersion, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersion + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.FindModelVersion") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_version" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiFindRegisteredModelRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string +} + +// Name of entity to search. +func (r ApiFindRegisteredModelRequest) Name(name string) ApiFindRegisteredModelRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiFindRegisteredModelRequest) ExternalID(externalID string) ApiFindRegisteredModelRequest { + r.externalID = &externalID + return r +} + +func (r ApiFindRegisteredModelRequest) Execute() (*RegisteredModel, *http.Response, error) { + return r.ApiService.FindRegisteredModelExecute(r) +} + +/* +FindRegisteredModel Get a RegisteredModel that matches search parameters. + +Gets the details of a single instance of a `RegisteredModel` that matches search parameters. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiFindRegisteredModelRequest +*/ +func (a *ModelRegistryServiceAPIService) FindRegisteredModel(ctx context.Context) ApiFindRegisteredModelRequest { + return ApiFindRegisteredModelRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return RegisteredModel +func (a *ModelRegistryServiceAPIService) FindRegisteredModelExecute(r ApiFindRegisteredModelRequest) (*RegisteredModel, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RegisteredModel + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.FindRegisteredModel") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/registered_model" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiFindServingEnvironmentRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string +} + +// Name of entity to search. +func (r ApiFindServingEnvironmentRequest) Name(name string) ApiFindServingEnvironmentRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiFindServingEnvironmentRequest) ExternalID(externalID string) ApiFindServingEnvironmentRequest { + r.externalID = &externalID + return r +} + +func (r ApiFindServingEnvironmentRequest) Execute() (*ServingEnvironment, *http.Response, error) { + return r.ApiService.FindServingEnvironmentExecute(r) +} + +/* +FindServingEnvironment Find ServingEnvironment + +Finds a `ServingEnvironment` entity that matches query parameters. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiFindServingEnvironmentRequest +*/ +func (a *ModelRegistryServiceAPIService) FindServingEnvironment(ctx context.Context) ApiFindServingEnvironmentRequest { + return ApiFindServingEnvironmentRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ServingEnvironment +func (a *ModelRegistryServiceAPIService) FindServingEnvironmentExecute(r ApiFindServingEnvironmentRequest) (*ServingEnvironment, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServingEnvironment + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.FindServingEnvironment") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/serving_environment" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetEnvironmentInferenceServicesRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + servingenvironmentId string + name *string + externalID *string + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Name of entity to search. +func (r ApiGetEnvironmentInferenceServicesRequest) Name(name string) ApiGetEnvironmentInferenceServicesRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiGetEnvironmentInferenceServicesRequest) ExternalID(externalID string) ApiGetEnvironmentInferenceServicesRequest { + r.externalID = &externalID + return r +} + +// Number of entities in each page. +func (r ApiGetEnvironmentInferenceServicesRequest) PageSize(pageSize string) ApiGetEnvironmentInferenceServicesRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetEnvironmentInferenceServicesRequest) OrderBy(orderBy OrderByField) ApiGetEnvironmentInferenceServicesRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetEnvironmentInferenceServicesRequest) SortOrder(sortOrder SortOrder) ApiGetEnvironmentInferenceServicesRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetEnvironmentInferenceServicesRequest) NextPageToken(nextPageToken string) ApiGetEnvironmentInferenceServicesRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetEnvironmentInferenceServicesRequest) Execute() (*InferenceServiceList, *http.Response, error) { + return r.ApiService.GetEnvironmentInferenceServicesExecute(r) +} + +/* +GetEnvironmentInferenceServices List All ServingEnvironment's InferenceServices + +Gets a list of all `InferenceService` entities for the `ServingEnvironment`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param servingenvironmentId A unique identifier for a `ServingEnvironment`. + @return ApiGetEnvironmentInferenceServicesRequest +*/ +func (a *ModelRegistryServiceAPIService) GetEnvironmentInferenceServices(ctx context.Context, servingenvironmentId string) ApiGetEnvironmentInferenceServicesRequest { + return ApiGetEnvironmentInferenceServicesRequest{ + ApiService: a, + ctx: ctx, + servingenvironmentId: servingenvironmentId, + } +} + +// Execute executes the request +// +// @return InferenceServiceList +func (a *ModelRegistryServiceAPIService) GetEnvironmentInferenceServicesExecute(r ApiGetEnvironmentInferenceServicesRequest) (*InferenceServiceList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *InferenceServiceList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetEnvironmentInferenceServices") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}/inference_services" + localVarPath = strings.Replace(localVarPath, "{"+"servingenvironmentId"+"}", url.PathEscape(parameterValueToString(r.servingenvironmentId, "servingenvironmentId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetInferenceServiceRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + inferenceserviceId string +} + +func (r ApiGetInferenceServiceRequest) Execute() (*InferenceService, *http.Response, error) { + return r.ApiService.GetInferenceServiceExecute(r) +} + +/* +GetInferenceService Get a InferenceService + +Gets the details of a single instance of a `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param inferenceserviceId A unique identifier for a `InferenceService`. + @return ApiGetInferenceServiceRequest +*/ +func (a *ModelRegistryServiceAPIService) GetInferenceService(ctx context.Context, inferenceserviceId string) ApiGetInferenceServiceRequest { + return ApiGetInferenceServiceRequest{ + ApiService: a, + ctx: ctx, + inferenceserviceId: inferenceserviceId, + } +} + +// Execute executes the request +// +// @return InferenceService +func (a *ModelRegistryServiceAPIService) GetInferenceServiceExecute(r ApiGetInferenceServiceRequest) (*InferenceService, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *InferenceService + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetInferenceService") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}" + localVarPath = strings.Replace(localVarPath, "{"+"inferenceserviceId"+"}", url.PathEscape(parameterValueToString(r.inferenceserviceId, "inferenceserviceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetInferenceServiceModelRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + inferenceserviceId string +} + +func (r ApiGetInferenceServiceModelRequest) Execute() (*RegisteredModel, *http.Response, error) { + return r.ApiService.GetInferenceServiceModelExecute(r) +} + +/* +GetInferenceServiceModel Get InferenceService's RegisteredModel + +Gets the `RegisteredModel` entity for the `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param inferenceserviceId A unique identifier for a `InferenceService`. + @return ApiGetInferenceServiceModelRequest +*/ +func (a *ModelRegistryServiceAPIService) GetInferenceServiceModel(ctx context.Context, inferenceserviceId string) ApiGetInferenceServiceModelRequest { + return ApiGetInferenceServiceModelRequest{ + ApiService: a, + ctx: ctx, + inferenceserviceId: inferenceserviceId, + } +} + +// Execute executes the request +// +// @return RegisteredModel +func (a *ModelRegistryServiceAPIService) GetInferenceServiceModelExecute(r ApiGetInferenceServiceModelRequest) (*RegisteredModel, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RegisteredModel + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetInferenceServiceModel") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/model" + localVarPath = strings.Replace(localVarPath, "{"+"inferenceserviceId"+"}", url.PathEscape(parameterValueToString(r.inferenceserviceId, "inferenceserviceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetInferenceServiceServesRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + inferenceserviceId string + name *string + externalID *string + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Name of entity to search. +func (r ApiGetInferenceServiceServesRequest) Name(name string) ApiGetInferenceServiceServesRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiGetInferenceServiceServesRequest) ExternalID(externalID string) ApiGetInferenceServiceServesRequest { + r.externalID = &externalID + return r +} + +// Number of entities in each page. +func (r ApiGetInferenceServiceServesRequest) PageSize(pageSize string) ApiGetInferenceServiceServesRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetInferenceServiceServesRequest) OrderBy(orderBy OrderByField) ApiGetInferenceServiceServesRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetInferenceServiceServesRequest) SortOrder(sortOrder SortOrder) ApiGetInferenceServiceServesRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetInferenceServiceServesRequest) NextPageToken(nextPageToken string) ApiGetInferenceServiceServesRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetInferenceServiceServesRequest) Execute() (*ServeModelList, *http.Response, error) { + return r.ApiService.GetInferenceServiceServesExecute(r) +} + +/* +GetInferenceServiceServes List All InferenceService's ServeModel actions + +Gets a list of all `ServeModel` entities for the `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param inferenceserviceId A unique identifier for a `InferenceService`. + @return ApiGetInferenceServiceServesRequest +*/ +func (a *ModelRegistryServiceAPIService) GetInferenceServiceServes(ctx context.Context, inferenceserviceId string) ApiGetInferenceServiceServesRequest { + return ApiGetInferenceServiceServesRequest{ + ApiService: a, + ctx: ctx, + inferenceserviceId: inferenceserviceId, + } +} + +// Execute executes the request +// +// @return ServeModelList +func (a *ModelRegistryServiceAPIService) GetInferenceServiceServesExecute(r ApiGetInferenceServiceServesRequest) (*ServeModelList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServeModelList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetInferenceServiceServes") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/serves" + localVarPath = strings.Replace(localVarPath, "{"+"inferenceserviceId"+"}", url.PathEscape(parameterValueToString(r.inferenceserviceId, "inferenceserviceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetInferenceServiceVersionRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + inferenceserviceId string +} + +func (r ApiGetInferenceServiceVersionRequest) Execute() (*ModelVersion, *http.Response, error) { + return r.ApiService.GetInferenceServiceVersionExecute(r) +} + +/* +GetInferenceServiceVersion Get InferenceService's ModelVersion + +Gets the `ModelVersion` entity for the `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param inferenceserviceId A unique identifier for a `InferenceService`. + @return ApiGetInferenceServiceVersionRequest +*/ +func (a *ModelRegistryServiceAPIService) GetInferenceServiceVersion(ctx context.Context, inferenceserviceId string) ApiGetInferenceServiceVersionRequest { + return ApiGetInferenceServiceVersionRequest{ + ApiService: a, + ctx: ctx, + inferenceserviceId: inferenceserviceId, + } +} + +// Execute executes the request +// +// @return ModelVersion +func (a *ModelRegistryServiceAPIService) GetInferenceServiceVersionExecute(r ApiGetInferenceServiceVersionRequest) (*ModelVersion, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersion + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetInferenceServiceVersion") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/version" + localVarPath = strings.Replace(localVarPath, "{"+"inferenceserviceId"+"}", url.PathEscape(parameterValueToString(r.inferenceserviceId, "inferenceserviceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetInferenceServicesRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Number of entities in each page. +func (r ApiGetInferenceServicesRequest) PageSize(pageSize string) ApiGetInferenceServicesRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetInferenceServicesRequest) OrderBy(orderBy OrderByField) ApiGetInferenceServicesRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetInferenceServicesRequest) SortOrder(sortOrder SortOrder) ApiGetInferenceServicesRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetInferenceServicesRequest) NextPageToken(nextPageToken string) ApiGetInferenceServicesRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetInferenceServicesRequest) Execute() (*InferenceServiceList, *http.Response, error) { + return r.ApiService.GetInferenceServicesExecute(r) +} + +/* +GetInferenceServices List All InferenceServices + +Gets a list of all `InferenceService` entities. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetInferenceServicesRequest +*/ +func (a *ModelRegistryServiceAPIService) GetInferenceServices(ctx context.Context) ApiGetInferenceServicesRequest { + return ApiGetInferenceServicesRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return InferenceServiceList +func (a *ModelRegistryServiceAPIService) GetInferenceServicesExecute(r ApiGetInferenceServicesRequest) (*InferenceServiceList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *InferenceServiceList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetInferenceServices") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetModelArtifactRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelartifactId string +} + +func (r ApiGetModelArtifactRequest) Execute() (*ModelArtifact, *http.Response, error) { + return r.ApiService.GetModelArtifactExecute(r) +} + +/* +GetModelArtifact Get a ModelArtifact + +Gets the details of a single instance of a `ModelArtifact`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param modelartifactId A unique identifier for a `ModelArtifact`. + @return ApiGetModelArtifactRequest +*/ +func (a *ModelRegistryServiceAPIService) GetModelArtifact(ctx context.Context, modelartifactId string) ApiGetModelArtifactRequest { + return ApiGetModelArtifactRequest{ + ApiService: a, + ctx: ctx, + modelartifactId: modelartifactId, + } +} + +// Execute executes the request +// +// @return ModelArtifact +func (a *ModelRegistryServiceAPIService) GetModelArtifactExecute(r ApiGetModelArtifactRequest) (*ModelArtifact, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelArtifact + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetModelArtifact") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_artifacts/{modelartifactId}" + localVarPath = strings.Replace(localVarPath, "{"+"modelartifactId"+"}", url.PathEscape(parameterValueToString(r.modelartifactId, "modelartifactId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetModelArtifactsRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Number of entities in each page. +func (r ApiGetModelArtifactsRequest) PageSize(pageSize string) ApiGetModelArtifactsRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetModelArtifactsRequest) OrderBy(orderBy OrderByField) ApiGetModelArtifactsRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetModelArtifactsRequest) SortOrder(sortOrder SortOrder) ApiGetModelArtifactsRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetModelArtifactsRequest) NextPageToken(nextPageToken string) ApiGetModelArtifactsRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetModelArtifactsRequest) Execute() (*ModelArtifactList, *http.Response, error) { + return r.ApiService.GetModelArtifactsExecute(r) +} + +/* +GetModelArtifacts List All ModelArtifacts + +Gets a list of all `ModelArtifact` entities. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetModelArtifactsRequest +*/ +func (a *ModelRegistryServiceAPIService) GetModelArtifacts(ctx context.Context) ApiGetModelArtifactsRequest { + return ApiGetModelArtifactsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelArtifactList +func (a *ModelRegistryServiceAPIService) GetModelArtifactsExecute(r ApiGetModelArtifactsRequest) (*ModelArtifactList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelArtifactList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetModelArtifacts") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_artifacts" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetModelVersionRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelversionId string +} + +func (r ApiGetModelVersionRequest) Execute() (*ModelVersion, *http.Response, error) { + return r.ApiService.GetModelVersionExecute(r) +} + +/* +GetModelVersion Get a ModelVersion + +Gets the details of a single instance of a `ModelVersion`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param modelversionId A unique identifier for a `ModelVersion`. + @return ApiGetModelVersionRequest +*/ +func (a *ModelRegistryServiceAPIService) GetModelVersion(ctx context.Context, modelversionId string) ApiGetModelVersionRequest { + return ApiGetModelVersionRequest{ + ApiService: a, + ctx: ctx, + modelversionId: modelversionId, + } +} + +// Execute executes the request +// +// @return ModelVersion +func (a *ModelRegistryServiceAPIService) GetModelVersionExecute(r ApiGetModelVersionRequest) (*ModelVersion, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersion + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetModelVersion") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_versions/{modelversionId}" + localVarPath = strings.Replace(localVarPath, "{"+"modelversionId"+"}", url.PathEscape(parameterValueToString(r.modelversionId, "modelversionId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetModelVersionArtifactsRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelversionId string + name *string + externalID *string + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Name of entity to search. +func (r ApiGetModelVersionArtifactsRequest) Name(name string) ApiGetModelVersionArtifactsRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiGetModelVersionArtifactsRequest) ExternalID(externalID string) ApiGetModelVersionArtifactsRequest { + r.externalID = &externalID + return r +} + +// Number of entities in each page. +func (r ApiGetModelVersionArtifactsRequest) PageSize(pageSize string) ApiGetModelVersionArtifactsRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetModelVersionArtifactsRequest) OrderBy(orderBy OrderByField) ApiGetModelVersionArtifactsRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetModelVersionArtifactsRequest) SortOrder(sortOrder SortOrder) ApiGetModelVersionArtifactsRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetModelVersionArtifactsRequest) NextPageToken(nextPageToken string) ApiGetModelVersionArtifactsRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetModelVersionArtifactsRequest) Execute() (*ArtifactList, *http.Response, error) { + return r.ApiService.GetModelVersionArtifactsExecute(r) +} + +/* +GetModelVersionArtifacts List All ModelVersion's artifacts + +Gets a list of all `Artifact` entities for the `ModelVersion`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param modelversionId A unique identifier for a `ModelVersion`. + @return ApiGetModelVersionArtifactsRequest +*/ +func (a *ModelRegistryServiceAPIService) GetModelVersionArtifacts(ctx context.Context, modelversionId string) ApiGetModelVersionArtifactsRequest { + return ApiGetModelVersionArtifactsRequest{ + ApiService: a, + ctx: ctx, + modelversionId: modelversionId, + } +} + +// Execute executes the request +// +// @return ArtifactList +func (a *ModelRegistryServiceAPIService) GetModelVersionArtifactsExecute(r ApiGetModelVersionArtifactsRequest) (*ArtifactList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ArtifactList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetModelVersionArtifacts") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts" + localVarPath = strings.Replace(localVarPath, "{"+"modelversionId"+"}", url.PathEscape(parameterValueToString(r.modelversionId, "modelversionId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetModelVersionsRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Number of entities in each page. +func (r ApiGetModelVersionsRequest) PageSize(pageSize string) ApiGetModelVersionsRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetModelVersionsRequest) OrderBy(orderBy OrderByField) ApiGetModelVersionsRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetModelVersionsRequest) SortOrder(sortOrder SortOrder) ApiGetModelVersionsRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetModelVersionsRequest) NextPageToken(nextPageToken string) ApiGetModelVersionsRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetModelVersionsRequest) Execute() (*ModelVersionList, *http.Response, error) { + return r.ApiService.GetModelVersionsExecute(r) +} + +/* +GetModelVersions List All ModelVersions + +Gets a list of all `ModelVersion` entities. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetModelVersionsRequest +*/ +func (a *ModelRegistryServiceAPIService) GetModelVersions(ctx context.Context) ApiGetModelVersionsRequest { + return ApiGetModelVersionsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ModelVersionList +func (a *ModelRegistryServiceAPIService) GetModelVersionsExecute(r ApiGetModelVersionsRequest) (*ModelVersionList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersionList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetModelVersions") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_versions" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetRegisteredModelRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + registeredmodelId string +} + +func (r ApiGetRegisteredModelRequest) Execute() (*RegisteredModel, *http.Response, error) { + return r.ApiService.GetRegisteredModelExecute(r) +} + +/* +GetRegisteredModel Get a RegisteredModel + +Gets the details of a single instance of a `RegisteredModel`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param registeredmodelId A unique identifier for a `RegisteredModel`. + @return ApiGetRegisteredModelRequest +*/ +func (a *ModelRegistryServiceAPIService) GetRegisteredModel(ctx context.Context, registeredmodelId string) ApiGetRegisteredModelRequest { + return ApiGetRegisteredModelRequest{ + ApiService: a, + ctx: ctx, + registeredmodelId: registeredmodelId, + } +} + +// Execute executes the request +// +// @return RegisteredModel +func (a *ModelRegistryServiceAPIService) GetRegisteredModelExecute(r ApiGetRegisteredModelRequest) (*RegisteredModel, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RegisteredModel + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetRegisteredModel") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}" + localVarPath = strings.Replace(localVarPath, "{"+"registeredmodelId"+"}", url.PathEscape(parameterValueToString(r.registeredmodelId, "registeredmodelId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetRegisteredModelVersionsRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + registeredmodelId string + name *string + externalID *string + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Name of entity to search. +func (r ApiGetRegisteredModelVersionsRequest) Name(name string) ApiGetRegisteredModelVersionsRequest { + r.name = &name + return r +} + +// External ID of entity to search. +func (r ApiGetRegisteredModelVersionsRequest) ExternalID(externalID string) ApiGetRegisteredModelVersionsRequest { + r.externalID = &externalID + return r +} + +// Number of entities in each page. +func (r ApiGetRegisteredModelVersionsRequest) PageSize(pageSize string) ApiGetRegisteredModelVersionsRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetRegisteredModelVersionsRequest) OrderBy(orderBy OrderByField) ApiGetRegisteredModelVersionsRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetRegisteredModelVersionsRequest) SortOrder(sortOrder SortOrder) ApiGetRegisteredModelVersionsRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetRegisteredModelVersionsRequest) NextPageToken(nextPageToken string) ApiGetRegisteredModelVersionsRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetRegisteredModelVersionsRequest) Execute() (*ModelVersionList, *http.Response, error) { + return r.ApiService.GetRegisteredModelVersionsExecute(r) +} + +/* +GetRegisteredModelVersions List All RegisteredModel's ModelVersions + +Gets a list of all `ModelVersion` entities for the `RegisteredModel`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param registeredmodelId A unique identifier for a `RegisteredModel`. + @return ApiGetRegisteredModelVersionsRequest +*/ +func (a *ModelRegistryServiceAPIService) GetRegisteredModelVersions(ctx context.Context, registeredmodelId string) ApiGetRegisteredModelVersionsRequest { + return ApiGetRegisteredModelVersionsRequest{ + ApiService: a, + ctx: ctx, + registeredmodelId: registeredmodelId, + } +} + +// Execute executes the request +// +// @return ModelVersionList +func (a *ModelRegistryServiceAPIService) GetRegisteredModelVersionsExecute(r ApiGetRegisteredModelVersionsRequest) (*ModelVersionList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersionList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetRegisteredModelVersions") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}/versions" + localVarPath = strings.Replace(localVarPath, "{"+"registeredmodelId"+"}", url.PathEscape(parameterValueToString(r.registeredmodelId, "registeredmodelId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.name != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "name", r.name, "") + } + if r.externalID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") + } + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetRegisteredModelsRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Number of entities in each page. +func (r ApiGetRegisteredModelsRequest) PageSize(pageSize string) ApiGetRegisteredModelsRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetRegisteredModelsRequest) OrderBy(orderBy OrderByField) ApiGetRegisteredModelsRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetRegisteredModelsRequest) SortOrder(sortOrder SortOrder) ApiGetRegisteredModelsRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetRegisteredModelsRequest) NextPageToken(nextPageToken string) ApiGetRegisteredModelsRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetRegisteredModelsRequest) Execute() (*RegisteredModelList, *http.Response, error) { + return r.ApiService.GetRegisteredModelsExecute(r) +} + +/* +GetRegisteredModels List All RegisteredModels + +Gets a list of all `RegisteredModel` entities. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetRegisteredModelsRequest +*/ +func (a *ModelRegistryServiceAPIService) GetRegisteredModels(ctx context.Context) ApiGetRegisteredModelsRequest { + return ApiGetRegisteredModelsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return RegisteredModelList +func (a *ModelRegistryServiceAPIService) GetRegisteredModelsExecute(r ApiGetRegisteredModelsRequest) (*RegisteredModelList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RegisteredModelList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetRegisteredModels") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/registered_models" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetServingEnvironmentRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + servingenvironmentId string +} + +func (r ApiGetServingEnvironmentRequest) Execute() (*ServingEnvironment, *http.Response, error) { + return r.ApiService.GetServingEnvironmentExecute(r) +} + +/* +GetServingEnvironment Get a ServingEnvironment + +Gets the details of a single instance of a `ServingEnvironment`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param servingenvironmentId A unique identifier for a `ServingEnvironment`. + @return ApiGetServingEnvironmentRequest +*/ +func (a *ModelRegistryServiceAPIService) GetServingEnvironment(ctx context.Context, servingenvironmentId string) ApiGetServingEnvironmentRequest { + return ApiGetServingEnvironmentRequest{ + ApiService: a, + ctx: ctx, + servingenvironmentId: servingenvironmentId, + } +} + +// Execute executes the request +// +// @return ServingEnvironment +func (a *ModelRegistryServiceAPIService) GetServingEnvironmentExecute(r ApiGetServingEnvironmentRequest) (*ServingEnvironment, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServingEnvironment + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetServingEnvironment") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}" + localVarPath = strings.Replace(localVarPath, "{"+"servingenvironmentId"+"}", url.PathEscape(parameterValueToString(r.servingenvironmentId, "servingenvironmentId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiGetServingEnvironmentsRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + pageSize *string + orderBy *OrderByField + sortOrder *SortOrder + nextPageToken *string +} + +// Number of entities in each page. +func (r ApiGetServingEnvironmentsRequest) PageSize(pageSize string) ApiGetServingEnvironmentsRequest { + r.pageSize = &pageSize + return r +} + +// Specifies the order by criteria for listing entities. +func (r ApiGetServingEnvironmentsRequest) OrderBy(orderBy OrderByField) ApiGetServingEnvironmentsRequest { + r.orderBy = &orderBy + return r +} + +// Specifies the sort order for listing entities, defaults to ASC. +func (r ApiGetServingEnvironmentsRequest) SortOrder(sortOrder SortOrder) ApiGetServingEnvironmentsRequest { + r.sortOrder = &sortOrder + return r +} + +// Token to use to retrieve next page of results. +func (r ApiGetServingEnvironmentsRequest) NextPageToken(nextPageToken string) ApiGetServingEnvironmentsRequest { + r.nextPageToken = &nextPageToken + return r +} + +func (r ApiGetServingEnvironmentsRequest) Execute() (*ServingEnvironmentList, *http.Response, error) { + return r.ApiService.GetServingEnvironmentsExecute(r) +} + +/* +GetServingEnvironments List All ServingEnvironments + +Gets a list of all `ServingEnvironment` entities. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiGetServingEnvironmentsRequest +*/ +func (a *ModelRegistryServiceAPIService) GetServingEnvironments(ctx context.Context) ApiGetServingEnvironmentsRequest { + return ApiGetServingEnvironmentsRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return ServingEnvironmentList +func (a *ModelRegistryServiceAPIService) GetServingEnvironmentsExecute(r ApiGetServingEnvironmentsRequest) (*ServingEnvironmentList, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServingEnvironmentList + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.GetServingEnvironments") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/serving_environments" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if r.pageSize != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "pageSize", r.pageSize, "") + } + if r.orderBy != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "orderBy", r.orderBy, "") + } + if r.sortOrder != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "sortOrder", r.sortOrder, "") + } + if r.nextPageToken != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "nextPageToken", r.nextPageToken, "") + } + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateInferenceServiceRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + inferenceserviceId string + inferenceServiceUpdate *InferenceServiceUpdate +} + +// Updated `InferenceService` information. +func (r ApiUpdateInferenceServiceRequest) InferenceServiceUpdate(inferenceServiceUpdate InferenceServiceUpdate) ApiUpdateInferenceServiceRequest { + r.inferenceServiceUpdate = &inferenceServiceUpdate + return r +} + +func (r ApiUpdateInferenceServiceRequest) Execute() (*InferenceService, *http.Response, error) { + return r.ApiService.UpdateInferenceServiceExecute(r) +} + +/* +UpdateInferenceService Update a InferenceService + +Updates an existing `InferenceService`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param inferenceserviceId A unique identifier for a `InferenceService`. + @return ApiUpdateInferenceServiceRequest +*/ +func (a *ModelRegistryServiceAPIService) UpdateInferenceService(ctx context.Context, inferenceserviceId string) ApiUpdateInferenceServiceRequest { + return ApiUpdateInferenceServiceRequest{ + ApiService: a, + ctx: ctx, + inferenceserviceId: inferenceserviceId, + } +} + +// Execute executes the request +// +// @return InferenceService +func (a *ModelRegistryServiceAPIService) UpdateInferenceServiceExecute(r ApiUpdateInferenceServiceRequest) (*InferenceService, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *InferenceService + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.UpdateInferenceService") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}" + localVarPath = strings.Replace(localVarPath, "{"+"inferenceserviceId"+"}", url.PathEscape(parameterValueToString(r.inferenceserviceId, "inferenceserviceId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.inferenceServiceUpdate == nil { + return localVarReturnValue, nil, reportError("inferenceServiceUpdate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.inferenceServiceUpdate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateModelArtifactRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelartifactId string + modelArtifactUpdate *ModelArtifactUpdate +} + +// Updated `ModelArtifact` information. +func (r ApiUpdateModelArtifactRequest) ModelArtifactUpdate(modelArtifactUpdate ModelArtifactUpdate) ApiUpdateModelArtifactRequest { + r.modelArtifactUpdate = &modelArtifactUpdate + return r +} + +func (r ApiUpdateModelArtifactRequest) Execute() (*ModelArtifact, *http.Response, error) { + return r.ApiService.UpdateModelArtifactExecute(r) +} + +/* +UpdateModelArtifact Update a ModelArtifact + +Updates an existing `ModelArtifact`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param modelartifactId A unique identifier for a `ModelArtifact`. + @return ApiUpdateModelArtifactRequest +*/ +func (a *ModelRegistryServiceAPIService) UpdateModelArtifact(ctx context.Context, modelartifactId string) ApiUpdateModelArtifactRequest { + return ApiUpdateModelArtifactRequest{ + ApiService: a, + ctx: ctx, + modelartifactId: modelartifactId, + } +} + +// Execute executes the request +// +// @return ModelArtifact +func (a *ModelRegistryServiceAPIService) UpdateModelArtifactExecute(r ApiUpdateModelArtifactRequest) (*ModelArtifact, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelArtifact + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.UpdateModelArtifact") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_artifacts/{modelartifactId}" + localVarPath = strings.Replace(localVarPath, "{"+"modelartifactId"+"}", url.PathEscape(parameterValueToString(r.modelartifactId, "modelartifactId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.modelArtifactUpdate == nil { + return localVarReturnValue, nil, reportError("modelArtifactUpdate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.modelArtifactUpdate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateModelVersionRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + modelversionId string + modelVersion *ModelVersion +} + +// Updated `ModelVersion` information. +func (r ApiUpdateModelVersionRequest) ModelVersion(modelVersion ModelVersion) ApiUpdateModelVersionRequest { + r.modelVersion = &modelVersion + return r +} + +func (r ApiUpdateModelVersionRequest) Execute() (*ModelVersion, *http.Response, error) { + return r.ApiService.UpdateModelVersionExecute(r) +} + +/* +UpdateModelVersion Update a ModelVersion + +Updates an existing `ModelVersion`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param modelversionId A unique identifier for a `ModelVersion`. + @return ApiUpdateModelVersionRequest +*/ +func (a *ModelRegistryServiceAPIService) UpdateModelVersion(ctx context.Context, modelversionId string) ApiUpdateModelVersionRequest { + return ApiUpdateModelVersionRequest{ + ApiService: a, + ctx: ctx, + modelversionId: modelversionId, + } +} + +// Execute executes the request +// +// @return ModelVersion +func (a *ModelRegistryServiceAPIService) UpdateModelVersionExecute(r ApiUpdateModelVersionRequest) (*ModelVersion, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ModelVersion + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.UpdateModelVersion") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/model_versions/{modelversionId}" + localVarPath = strings.Replace(localVarPath, "{"+"modelversionId"+"}", url.PathEscape(parameterValueToString(r.modelversionId, "modelversionId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.modelVersion == nil { + return localVarReturnValue, nil, reportError("modelVersion is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.modelVersion + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateRegisteredModelRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + registeredmodelId string + registeredModelUpdate *RegisteredModelUpdate +} + +// Updated `RegisteredModel` information. +func (r ApiUpdateRegisteredModelRequest) RegisteredModelUpdate(registeredModelUpdate RegisteredModelUpdate) ApiUpdateRegisteredModelRequest { + r.registeredModelUpdate = ®isteredModelUpdate + return r +} + +func (r ApiUpdateRegisteredModelRequest) Execute() (*RegisteredModel, *http.Response, error) { + return r.ApiService.UpdateRegisteredModelExecute(r) +} + +/* +UpdateRegisteredModel Update a RegisteredModel + +Updates an existing `RegisteredModel`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param registeredmodelId A unique identifier for a `RegisteredModel`. + @return ApiUpdateRegisteredModelRequest +*/ +func (a *ModelRegistryServiceAPIService) UpdateRegisteredModel(ctx context.Context, registeredmodelId string) ApiUpdateRegisteredModelRequest { + return ApiUpdateRegisteredModelRequest{ + ApiService: a, + ctx: ctx, + registeredmodelId: registeredmodelId, + } +} + +// Execute executes the request +// +// @return RegisteredModel +func (a *ModelRegistryServiceAPIService) UpdateRegisteredModelExecute(r ApiUpdateRegisteredModelRequest) (*RegisteredModel, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *RegisteredModel + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.UpdateRegisteredModel") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}" + localVarPath = strings.Replace(localVarPath, "{"+"registeredmodelId"+"}", url.PathEscape(parameterValueToString(r.registeredmodelId, "registeredmodelId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.registeredModelUpdate == nil { + return localVarReturnValue, nil, reportError("registeredModelUpdate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.registeredModelUpdate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + +type ApiUpdateServingEnvironmentRequest struct { + ctx context.Context + ApiService *ModelRegistryServiceAPIService + servingenvironmentId string + servingEnvironmentUpdate *ServingEnvironmentUpdate +} + +// Updated `ServingEnvironment` information. +func (r ApiUpdateServingEnvironmentRequest) ServingEnvironmentUpdate(servingEnvironmentUpdate ServingEnvironmentUpdate) ApiUpdateServingEnvironmentRequest { + r.servingEnvironmentUpdate = &servingEnvironmentUpdate + return r +} + +func (r ApiUpdateServingEnvironmentRequest) Execute() (*ServingEnvironment, *http.Response, error) { + return r.ApiService.UpdateServingEnvironmentExecute(r) +} + +/* +UpdateServingEnvironment Update a ServingEnvironment + +Updates an existing `ServingEnvironment`. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param servingenvironmentId A unique identifier for a `ServingEnvironment`. + @return ApiUpdateServingEnvironmentRequest +*/ +func (a *ModelRegistryServiceAPIService) UpdateServingEnvironment(ctx context.Context, servingenvironmentId string) ApiUpdateServingEnvironmentRequest { + return ApiUpdateServingEnvironmentRequest{ + ApiService: a, + ctx: ctx, + servingenvironmentId: servingenvironmentId, + } +} + +// Execute executes the request +// +// @return ServingEnvironment +func (a *ModelRegistryServiceAPIService) UpdateServingEnvironmentExecute(r ApiUpdateServingEnvironmentRequest) (*ServingEnvironment, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *ServingEnvironment + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "ModelRegistryServiceAPIService.UpdateServingEnvironment") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}" + localVarPath = strings.Replace(localVarPath, "{"+"servingenvironmentId"+"}", url.PathEscape(parameterValueToString(r.servingenvironmentId, "servingenvironmentId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.servingEnvironmentUpdate == nil { + return localVarReturnValue, nil, reportError("servingEnvironmentUpdate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.servingEnvironmentUpdate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + if localVarHTTPResponse.StatusCode == 400 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 401 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 404 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + if localVarHTTPResponse.StatusCode == 500 { + var v Error + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/internal/model/openapi/client.go b/internal/model/openapi/client.go new file mode 100644 index 00000000..2379badf --- /dev/null +++ b/internal/model/openapi/client.go @@ -0,0 +1,666 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "bytes" + "context" + "encoding/json" + "encoding/xml" + "errors" + "fmt" + "io" + "log" + "mime/multipart" + "net/http" + "net/http/httputil" + "net/url" + "os" + "path/filepath" + "reflect" + "regexp" + "strconv" + "strings" + "time" + "unicode/utf8" +) + +var ( + jsonCheck = regexp.MustCompile(`(?i:(?:application|text)/(?:vnd\.[^;]+\+)?json)`) + xmlCheck = regexp.MustCompile(`(?i:(?:application|text)/xml)`) + queryParamSplit = regexp.MustCompile(`(^|&)([^&]+)`) + queryDescape = strings.NewReplacer("%5B", "[", "%5D", "]") +) + +// APIClient manages communication with the Model Registry REST API API v1.0.0 +// In most cases there should be only one, shared, APIClient. +type APIClient struct { + cfg *Configuration + common service // Reuse a single struct instead of allocating one for each service on the heap. + + // API Services + + ModelRegistryServiceAPI *ModelRegistryServiceAPIService +} + +type service struct { + client *APIClient +} + +// NewAPIClient creates a new API client. Requires a userAgent string describing your application. +// optionally a custom http.Client to allow for advanced features such as caching. +func NewAPIClient(cfg *Configuration) *APIClient { + if cfg.HTTPClient == nil { + cfg.HTTPClient = http.DefaultClient + } + + c := &APIClient{} + c.cfg = cfg + c.common.client = c + + // API Services + c.ModelRegistryServiceAPI = (*ModelRegistryServiceAPIService)(&c.common) + + return c +} + +func atoi(in string) (int, error) { + return strconv.Atoi(in) +} + +// selectHeaderContentType select a content type from the available list. +func selectHeaderContentType(contentTypes []string) string { + if len(contentTypes) == 0 { + return "" + } + if contains(contentTypes, "application/json") { + return "application/json" + } + return contentTypes[0] // use the first content type specified in 'consumes' +} + +// selectHeaderAccept join all accept types and return +func selectHeaderAccept(accepts []string) string { + if len(accepts) == 0 { + return "" + } + + if contains(accepts, "application/json") { + return "application/json" + } + + return strings.Join(accepts, ",") +} + +// contains is a case insensitive match, finding needle in a haystack +func contains(haystack []string, needle string) bool { + for _, a := range haystack { + if strings.EqualFold(a, needle) { + return true + } + } + return false +} + +// Verify optional parameters are of the correct type. +func typeCheckParameter(obj interface{}, expected string, name string) error { + // Make sure there is an object. + if obj == nil { + return nil + } + + // Check the type is as expected. + if reflect.TypeOf(obj).String() != expected { + return fmt.Errorf("expected %s to be of type %s but received %s", name, expected, reflect.TypeOf(obj).String()) + } + return nil +} + +func parameterValueToString(obj interface{}, key string) string { + if reflect.TypeOf(obj).Kind() != reflect.Ptr { + return fmt.Sprintf("%v", obj) + } + var param, ok = obj.(MappedNullable) + if !ok { + return "" + } + dataMap, err := param.ToMap() + if err != nil { + return "" + } + return fmt.Sprintf("%v", dataMap[key]) +} + +// parameterAddToHeaderOrQuery adds the provided object to the request header or url query +// supporting deep object syntax +func parameterAddToHeaderOrQuery(headerOrQueryParams interface{}, keyPrefix string, obj interface{}, collectionType string) { + var v = reflect.ValueOf(obj) + var value = "" + if v == reflect.ValueOf(nil) { + value = "null" + } else { + switch v.Kind() { + case reflect.Invalid: + value = "invalid" + + case reflect.Struct: + if t, ok := obj.(MappedNullable); ok { + dataMap, err := t.ToMap() + if err != nil { + return + } + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, dataMap, collectionType) + return + } + if t, ok := obj.(time.Time); ok { + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, t.Format(time.RFC3339), collectionType) + return + } + value = v.Type().String() + " value" + case reflect.Slice: + var indValue = reflect.ValueOf(obj) + if indValue == reflect.ValueOf(nil) { + return + } + var lenIndValue = indValue.Len() + for i := 0; i < lenIndValue; i++ { + var arrayValue = indValue.Index(i) + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, arrayValue.Interface(), collectionType) + } + return + + case reflect.Map: + var indValue = reflect.ValueOf(obj) + if indValue == reflect.ValueOf(nil) { + return + } + iter := indValue.MapRange() + for iter.Next() { + k, v := iter.Key(), iter.Value() + parameterAddToHeaderOrQuery(headerOrQueryParams, fmt.Sprintf("%s[%s]", keyPrefix, k.String()), v.Interface(), collectionType) + } + return + + case reflect.Interface: + fallthrough + case reflect.Ptr: + parameterAddToHeaderOrQuery(headerOrQueryParams, keyPrefix, v.Elem().Interface(), collectionType) + return + + case reflect.Int, reflect.Int8, reflect.Int16, + reflect.Int32, reflect.Int64: + value = strconv.FormatInt(v.Int(), 10) + case reflect.Uint, reflect.Uint8, reflect.Uint16, + reflect.Uint32, reflect.Uint64, reflect.Uintptr: + value = strconv.FormatUint(v.Uint(), 10) + case reflect.Float32, reflect.Float64: + value = strconv.FormatFloat(v.Float(), 'g', -1, 32) + case reflect.Bool: + value = strconv.FormatBool(v.Bool()) + case reflect.String: + value = v.String() + default: + value = v.Type().String() + " value" + } + } + + switch valuesMap := headerOrQueryParams.(type) { + case url.Values: + if collectionType == "csv" && valuesMap.Get(keyPrefix) != "" { + valuesMap.Set(keyPrefix, valuesMap.Get(keyPrefix)+","+value) + } else { + valuesMap.Add(keyPrefix, value) + } + break + case map[string]string: + valuesMap[keyPrefix] = value + break + } +} + +// helper for converting interface{} parameters to json strings +func parameterToJson(obj interface{}) (string, error) { + jsonBuf, err := json.Marshal(obj) + if err != nil { + return "", err + } + return string(jsonBuf), err +} + +// callAPI do the request. +func (c *APIClient) callAPI(request *http.Request) (*http.Response, error) { + if c.cfg.Debug { + dump, err := httputil.DumpRequestOut(request, true) + if err != nil { + return nil, err + } + log.Printf("\n%s\n", string(dump)) + } + + resp, err := c.cfg.HTTPClient.Do(request) + if err != nil { + return resp, err + } + + if c.cfg.Debug { + dump, err := httputil.DumpResponse(resp, true) + if err != nil { + return resp, err + } + log.Printf("\n%s\n", string(dump)) + } + return resp, err +} + +// Allow modification of underlying config for alternate implementations and testing +// Caution: modifying the configuration while live can cause data races and potentially unwanted behavior +func (c *APIClient) GetConfig() *Configuration { + return c.cfg +} + +type formFile struct { + fileBytes []byte + fileName string + formFileName string +} + +// prepareRequest build the request +func (c *APIClient) prepareRequest( + ctx context.Context, + path string, method string, + postBody interface{}, + headerParams map[string]string, + queryParams url.Values, + formParams url.Values, + formFiles []formFile) (localVarRequest *http.Request, err error) { + + var body *bytes.Buffer + + // Detect postBody type and post. + if postBody != nil { + contentType := headerParams["Content-Type"] + if contentType == "" { + contentType = detectContentType(postBody) + headerParams["Content-Type"] = contentType + } + + body, err = setBody(postBody, contentType) + if err != nil { + return nil, err + } + } + + // add form parameters and file if available. + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(formFiles) > 0) { + if body != nil { + return nil, errors.New("Cannot specify postBody and multipart form at the same time.") + } + body = &bytes.Buffer{} + w := multipart.NewWriter(body) + + for k, v := range formParams { + for _, iv := range v { + if strings.HasPrefix(k, "@") { // file + err = addFile(w, k[1:], iv) + if err != nil { + return nil, err + } + } else { // form value + w.WriteField(k, iv) + } + } + } + for _, formFile := range formFiles { + if len(formFile.fileBytes) > 0 && formFile.fileName != "" { + w.Boundary() + part, err := w.CreateFormFile(formFile.formFileName, filepath.Base(formFile.fileName)) + if err != nil { + return nil, err + } + _, err = part.Write(formFile.fileBytes) + if err != nil { + return nil, err + } + } + } + + // Set the Boundary in the Content-Type + headerParams["Content-Type"] = w.FormDataContentType() + + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + w.Close() + } + + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + + // Setup path and query parameters + url, err := url.Parse(path) + if err != nil { + return nil, err + } + + // Override request host, if applicable + if c.cfg.Host != "" { + url.Host = c.cfg.Host + } + + // Override request scheme, if applicable + if c.cfg.Scheme != "" { + url.Scheme = c.cfg.Scheme + } + + // Adding Query Param + query := url.Query() + for k, v := range queryParams { + for _, iv := range v { + query.Add(k, iv) + } + } + + // Encode the parameters. + url.RawQuery = queryParamSplit.ReplaceAllStringFunc(query.Encode(), func(s string) string { + pieces := strings.Split(s, "=") + pieces[0] = queryDescape.Replace(pieces[0]) + return strings.Join(pieces, "=") + }) + + // Generate a new request + if body != nil { + localVarRequest, err = http.NewRequest(method, url.String(), body) + } else { + localVarRequest, err = http.NewRequest(method, url.String(), nil) + } + if err != nil { + return nil, err + } + + // add header parameters, if any + if len(headerParams) > 0 { + headers := http.Header{} + for h, v := range headerParams { + headers[h] = []string{v} + } + localVarRequest.Header = headers + } + + // Add the user agent to the request. + localVarRequest.Header.Add("User-Agent", c.cfg.UserAgent) + + if ctx != nil { + // add context to the request + localVarRequest = localVarRequest.WithContext(ctx) + + // Walk through any authentication. + + // AccessToken Authentication + if auth, ok := ctx.Value(ContextAccessToken).(string); ok { + localVarRequest.Header.Add("Authorization", "Bearer "+auth) + } + + } + + for header, value := range c.cfg.DefaultHeader { + localVarRequest.Header.Add(header, value) + } + return localVarRequest, nil +} + +func (c *APIClient) decode(v interface{}, b []byte, contentType string) (err error) { + if len(b) == 0 { + return nil + } + if s, ok := v.(*string); ok { + *s = string(b) + return nil + } + if f, ok := v.(*os.File); ok { + f, err = os.CreateTemp("", "HttpClientFile") + if err != nil { + return + } + _, err = f.Write(b) + if err != nil { + return + } + _, err = f.Seek(0, io.SeekStart) + err = os.Remove(f.Name()) + return + } + if f, ok := v.(**os.File); ok { + *f, err = os.CreateTemp("", "HttpClientFile") + if err != nil { + return + } + _, err = (*f).Write(b) + if err != nil { + return + } + _, err = (*f).Seek(0, io.SeekStart) + err = os.Remove((*f).Name()) + return + } + if xmlCheck.MatchString(contentType) { + if err = xml.Unmarshal(b, v); err != nil { + return err + } + return nil + } + if jsonCheck.MatchString(contentType) { + if actualObj, ok := v.(interface{ GetActualInstance() interface{} }); ok { // oneOf, anyOf schemas + if unmarshalObj, ok := actualObj.(interface{ UnmarshalJSON([]byte) error }); ok { // make sure it has UnmarshalJSON defined + if err = unmarshalObj.UnmarshalJSON(b); err != nil { + return err + } + } else { + return errors.New("Unknown type with GetActualInstance but no unmarshalObj.UnmarshalJSON defined") + } + } else if err = json.Unmarshal(b, v); err != nil { // simple model + return err + } + return nil + } + return errors.New("undefined response type") +} + +// Add a file to the multipart request +func addFile(w *multipart.Writer, fieldName, path string) error { + file, err := os.Open(filepath.Clean(path)) + if err != nil { + return err + } + err = file.Close() + if err != nil { + return err + } + + part, err := w.CreateFormFile(fieldName, filepath.Base(path)) + if err != nil { + return err + } + _, err = io.Copy(part, file) + + return err +} + +// Prevent trying to import "fmt" +func reportError(format string, a ...interface{}) error { + return fmt.Errorf(format, a...) +} + +// A wrapper for strict JSON decoding +func newStrictDecoder(data []byte) *json.Decoder { + dec := json.NewDecoder(bytes.NewBuffer(data)) + dec.DisallowUnknownFields() + return dec +} + +// Set request body from an interface{} +func setBody(body interface{}, contentType string) (bodyBuf *bytes.Buffer, err error) { + if bodyBuf == nil { + bodyBuf = &bytes.Buffer{} + } + + if reader, ok := body.(io.Reader); ok { + _, err = bodyBuf.ReadFrom(reader) + } else if fp, ok := body.(*os.File); ok { + _, err = bodyBuf.ReadFrom(fp) + } else if b, ok := body.([]byte); ok { + _, err = bodyBuf.Write(b) + } else if s, ok := body.(string); ok { + _, err = bodyBuf.WriteString(s) + } else if s, ok := body.(*string); ok { + _, err = bodyBuf.WriteString(*s) + } else if jsonCheck.MatchString(contentType) { + err = json.NewEncoder(bodyBuf).Encode(body) + } else if xmlCheck.MatchString(contentType) { + var bs []byte + bs, err = xml.Marshal(body) + if err == nil { + bodyBuf.Write(bs) + } + } + + if err != nil { + return nil, err + } + + if bodyBuf.Len() == 0 { + err = fmt.Errorf("invalid body type %s\n", contentType) + return nil, err + } + return bodyBuf, nil +} + +// detectContentType method is used to figure out `Request.Body` content type for request header +func detectContentType(body interface{}) string { + contentType := "text/plain; charset=utf-8" + kind := reflect.TypeOf(body).Kind() + + switch kind { + case reflect.Struct, reflect.Map, reflect.Ptr: + contentType = "application/json; charset=utf-8" + case reflect.String: + contentType = "text/plain; charset=utf-8" + default: + if b, ok := body.([]byte); ok { + contentType = http.DetectContentType(b) + } else if kind == reflect.Slice { + contentType = "application/json; charset=utf-8" + } + } + + return contentType +} + +// Ripped from https://github.com/gregjones/httpcache/blob/master/httpcache.go +type cacheControl map[string]string + +func parseCacheControl(headers http.Header) cacheControl { + cc := cacheControl{} + ccHeader := headers.Get("Cache-Control") + for _, part := range strings.Split(ccHeader, ",") { + part = strings.Trim(part, " ") + if part == "" { + continue + } + if strings.ContainsRune(part, '=') { + keyval := strings.Split(part, "=") + cc[strings.Trim(keyval[0], " ")] = strings.Trim(keyval[1], ",") + } else { + cc[part] = "" + } + } + return cc +} + +// CacheExpires helper function to determine remaining time before repeating a request. +func CacheExpires(r *http.Response) time.Time { + // Figure out when the cache expires. + var expires time.Time + now, err := time.Parse(time.RFC1123, r.Header.Get("date")) + if err != nil { + return time.Now() + } + respCacheControl := parseCacheControl(r.Header) + + if maxAge, ok := respCacheControl["max-age"]; ok { + lifetime, err := time.ParseDuration(maxAge + "s") + if err != nil { + expires = now + } else { + expires = now.Add(lifetime) + } + } else { + expiresHeader := r.Header.Get("Expires") + if expiresHeader != "" { + expires, err = time.Parse(time.RFC1123, expiresHeader) + if err != nil { + expires = now + } + } + } + return expires +} + +func strlen(s string) int { + return utf8.RuneCountInString(s) +} + +// GenericOpenAPIError Provides access to the body, error and model on returned errors. +type GenericOpenAPIError struct { + body []byte + error string + model interface{} +} + +// Error returns non-empty string if there was an error. +func (e GenericOpenAPIError) Error() string { + return e.error +} + +// Body returns the raw bytes of the response +func (e GenericOpenAPIError) Body() []byte { + return e.body +} + +// Model returns the unpacked model of the error +func (e GenericOpenAPIError) Model() interface{} { + return e.model +} + +// format error message using title and detail when model implements rfc7807 +func formatErrorMessage(status string, v interface{}) string { + str := "" + metaValue := reflect.ValueOf(v).Elem() + + if metaValue.Kind() == reflect.Struct { + field := metaValue.FieldByName("Title") + if field != (reflect.Value{}) { + str = fmt.Sprintf("%s", field.Interface()) + } + + field = metaValue.FieldByName("Detail") + if field != (reflect.Value{}) { + str = fmt.Sprintf("%s (%s)", str, field.Interface()) + } + } + + return strings.TrimSpace(fmt.Sprintf("%s %s", status, str)) +} diff --git a/internal/model/openapi/configuration.go b/internal/model/openapi/configuration.go new file mode 100644 index 00000000..28faea4a --- /dev/null +++ b/internal/model/openapi/configuration.go @@ -0,0 +1,217 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "context" + "fmt" + "net/http" + "strings" +) + +// contextKeys are used to identify the type of value in the context. +// Since these are string, it is possible to get a short description of the +// context key for logging and debugging using key.String(). + +type contextKey string + +func (c contextKey) String() string { + return "auth " + string(c) +} + +var ( + // ContextAccessToken takes a string oauth2 access token as authentication for the request. + ContextAccessToken = contextKey("accesstoken") + + // ContextServerIndex uses a server configuration from the index. + ContextServerIndex = contextKey("serverIndex") + + // ContextOperationServerIndices uses a server configuration from the index mapping. + ContextOperationServerIndices = contextKey("serverOperationIndices") + + // ContextServerVariables overrides a server configuration variables. + ContextServerVariables = contextKey("serverVariables") + + // ContextOperationServerVariables overrides a server configuration variables using operation specific values. + ContextOperationServerVariables = contextKey("serverOperationVariables") +) + +// BasicAuth provides basic http authentication to a request passed via context using ContextBasicAuth +type BasicAuth struct { + UserName string `json:"userName,omitempty"` + Password string `json:"password,omitempty"` +} + +// APIKey provides API key based authentication to a request passed via context using ContextAPIKey +type APIKey struct { + Key string + Prefix string +} + +// ServerVariable stores the information about a server variable +type ServerVariable struct { + Description string + DefaultValue string + EnumValues []string +} + +// ServerConfiguration stores the information about a server +type ServerConfiguration struct { + URL string + Description string + Variables map[string]ServerVariable +} + +// ServerConfigurations stores multiple ServerConfiguration items +type ServerConfigurations []ServerConfiguration + +// Configuration stores the configuration of the API client +type Configuration struct { + Host string `json:"host,omitempty"` + Scheme string `json:"scheme,omitempty"` + DefaultHeader map[string]string `json:"defaultHeader,omitempty"` + UserAgent string `json:"userAgent,omitempty"` + Debug bool `json:"debug,omitempty"` + Servers ServerConfigurations + OperationServers map[string]ServerConfigurations + HTTPClient *http.Client +} + +// NewConfiguration returns a new Configuration object +func NewConfiguration() *Configuration { + cfg := &Configuration{ + DefaultHeader: make(map[string]string), + UserAgent: "OpenAPI-Generator/1.0.0/go", + Debug: false, + Servers: ServerConfigurations{ + { + URL: "https://localhost:8080", + Description: "No description provided", + }, + }, + OperationServers: map[string]ServerConfigurations{}, + } + return cfg +} + +// AddDefaultHeader adds a new HTTP header to the default header in the request +func (c *Configuration) AddDefaultHeader(key string, value string) { + c.DefaultHeader[key] = value +} + +// URL formats template on a index using given variables +func (sc ServerConfigurations) URL(index int, variables map[string]string) (string, error) { + if index < 0 || len(sc) <= index { + return "", fmt.Errorf("index %v out of range %v", index, len(sc)-1) + } + server := sc[index] + url := server.URL + + // go through variables and replace placeholders + for name, variable := range server.Variables { + if value, ok := variables[name]; ok { + found := bool(len(variable.EnumValues) == 0) + for _, enumValue := range variable.EnumValues { + if value == enumValue { + found = true + } + } + if !found { + return "", fmt.Errorf("the variable %s in the server URL has invalid value %v. Must be %v", name, value, variable.EnumValues) + } + url = strings.Replace(url, "{"+name+"}", value, -1) + } else { + url = strings.Replace(url, "{"+name+"}", variable.DefaultValue, -1) + } + } + return url, nil +} + +// ServerURL returns URL based on server settings +func (c *Configuration) ServerURL(index int, variables map[string]string) (string, error) { + return c.Servers.URL(index, variables) +} + +func getServerIndex(ctx context.Context) (int, error) { + si := ctx.Value(ContextServerIndex) + if si != nil { + if index, ok := si.(int); ok { + return index, nil + } + return 0, reportError("Invalid type %T should be int", si) + } + return 0, nil +} + +func getServerOperationIndex(ctx context.Context, endpoint string) (int, error) { + osi := ctx.Value(ContextOperationServerIndices) + if osi != nil { + if operationIndices, ok := osi.(map[string]int); !ok { + return 0, reportError("Invalid type %T should be map[string]int", osi) + } else { + index, ok := operationIndices[endpoint] + if ok { + return index, nil + } + } + } + return getServerIndex(ctx) +} + +func getServerVariables(ctx context.Context) (map[string]string, error) { + sv := ctx.Value(ContextServerVariables) + if sv != nil { + if variables, ok := sv.(map[string]string); ok { + return variables, nil + } + return nil, reportError("ctx value of ContextServerVariables has invalid type %T should be map[string]string", sv) + } + return nil, nil +} + +func getServerOperationVariables(ctx context.Context, endpoint string) (map[string]string, error) { + osv := ctx.Value(ContextOperationServerVariables) + if osv != nil { + if operationVariables, ok := osv.(map[string]map[string]string); !ok { + return nil, reportError("ctx value of ContextOperationServerVariables has invalid type %T should be map[string]map[string]string", osv) + } else { + variables, ok := operationVariables[endpoint] + if ok { + return variables, nil + } + } + } + return getServerVariables(ctx) +} + +// ServerURLWithContext returns a new server URL given an endpoint +func (c *Configuration) ServerURLWithContext(ctx context.Context, endpoint string) (string, error) { + sc, ok := c.OperationServers[endpoint] + if !ok { + sc = c.Servers + } + + if ctx == nil { + return sc.URL(0, nil) + } + + index, err := getServerOperationIndex(ctx, endpoint) + if err != nil { + return "", err + } + + variables, err := getServerOperationVariables(ctx, endpoint) + if err != nil { + return "", err + } + + return sc.URL(index, variables) +} diff --git a/internal/model/openapi/model_artifact.go b/internal/model/openapi/model_artifact.go new file mode 100644 index 00000000..af2f5b89 --- /dev/null +++ b/internal/model/openapi/model_artifact.go @@ -0,0 +1,123 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// Artifact - A metadata Artifact Entity. +type Artifact struct { + ModelArtifact *ModelArtifact +} + +// ModelArtifactAsArtifact is a convenience function that returns ModelArtifact wrapped in Artifact +func ModelArtifactAsArtifact(v *ModelArtifact) Artifact { + return Artifact{ + ModelArtifact: v, + } +} + +// Unmarshal JSON data into one of the pointers in the struct +func (dst *Artifact) UnmarshalJSON(data []byte) error { + var err error + // use discriminator value to speed up the lookup + var jsonDict map[string]interface{} + err = newStrictDecoder(data).Decode(&jsonDict) + if err != nil { + return fmt.Errorf("failed to unmarshal JSON into map for the discriminator lookup") + } + + // check if the discriminator value is 'ModelArtifact' + if jsonDict["artifactType"] == "ModelArtifact" { + // try to unmarshal JSON data into ModelArtifact + err = json.Unmarshal(data, &dst.ModelArtifact) + if err == nil { + return nil // data stored in dst.ModelArtifact, return on the first match + } else { + dst.ModelArtifact = nil + return fmt.Errorf("failed to unmarshal Artifact as ModelArtifact: %s", err.Error()) + } + } + + // check if the discriminator value is 'model-artifact' + if jsonDict["artifactType"] == "model-artifact" { + // try to unmarshal JSON data into ModelArtifact + err = json.Unmarshal(data, &dst.ModelArtifact) + if err == nil { + return nil // data stored in dst.ModelArtifact, return on the first match + } else { + dst.ModelArtifact = nil + return fmt.Errorf("failed to unmarshal Artifact as ModelArtifact: %s", err.Error()) + } + } + + return nil +} + +// Marshal data from the first non-nil pointers in the struct to JSON +func (src Artifact) MarshalJSON() ([]byte, error) { + if src.ModelArtifact != nil { + return json.Marshal(&src.ModelArtifact) + } + + return nil, nil // no data in oneOf schemas +} + +// Get the actual instance +func (obj *Artifact) GetActualInstance() interface{} { + if obj == nil { + return nil + } + if obj.ModelArtifact != nil { + return obj.ModelArtifact + } + + // all schemas are nil + return nil +} + +type NullableArtifact struct { + value *Artifact + isSet bool +} + +func (v NullableArtifact) Get() *Artifact { + return v.value +} + +func (v *NullableArtifact) Set(val *Artifact) { + v.value = val + v.isSet = true +} + +func (v NullableArtifact) IsSet() bool { + return v.isSet +} + +func (v *NullableArtifact) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableArtifact(val *Artifact) *NullableArtifact { + return &NullableArtifact{value: val, isSet: true} +} + +func (v NullableArtifact) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableArtifact) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_artifact_list.go b/internal/model/openapi/model_artifact_list.go new file mode 100644 index 00000000..6eae5347 --- /dev/null +++ b/internal/model/openapi/model_artifact_list.go @@ -0,0 +1,209 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ArtifactList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ArtifactList{} + +// ArtifactList A list of Artifact entities. +type ArtifactList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` + // Array of `Artifact` entities. + Items []Artifact `json:"items,omitempty"` +} + +// NewArtifactList instantiates a new ArtifactList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewArtifactList(nextPageToken string, pageSize int32, size int32) *ArtifactList { + this := ArtifactList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewArtifactListWithDefaults instantiates a new ArtifactList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewArtifactListWithDefaults() *ArtifactList { + this := ArtifactList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *ArtifactList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *ArtifactList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *ArtifactList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *ArtifactList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *ArtifactList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *ArtifactList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *ArtifactList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *ArtifactList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *ArtifactList) SetSize(v int32) { + o.Size = v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *ArtifactList) GetItems() []Artifact { + if o == nil || IsNil(o.Items) { + var ret []Artifact + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ArtifactList) GetItemsOk() ([]Artifact, bool) { + if o == nil || IsNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *ArtifactList) HasItems() bool { + if o != nil && !IsNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []Artifact and assigns it to the Items field. +func (o *ArtifactList) SetItems(v []Artifact) { + o.Items = v +} + +func (o ArtifactList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ArtifactList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + if !IsNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableArtifactList struct { + value *ArtifactList + isSet bool +} + +func (v NullableArtifactList) Get() *ArtifactList { + return v.value +} + +func (v *NullableArtifactList) Set(val *ArtifactList) { + v.value = val + v.isSet = true +} + +func (v NullableArtifactList) IsSet() bool { + return v.isSet +} + +func (v *NullableArtifactList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableArtifactList(val *ArtifactList) *NullableArtifactList { + return &NullableArtifactList{value: val, isSet: true} +} + +func (v NullableArtifactList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableArtifactList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_artifact_state.go b/internal/model/openapi/model_artifact_state.go new file mode 100644 index 00000000..d377ac0d --- /dev/null +++ b/internal/model/openapi/model_artifact_state.go @@ -0,0 +1,120 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// ArtifactState - PENDING: A state indicating that the artifact may exist. - LIVE: A state indicating that the artifact should exist, unless something external to the system deletes it. - MARKED_FOR_DELETION: A state indicating that the artifact should be deleted. - DELETED: A state indicating that the artifact has been deleted. - ABANDONED: A state indicating that the artifact has been abandoned, which may be due to a failed or cancelled execution. - REFERENCE: A state indicating that the artifact is a reference artifact. At execution start time, the orchestrator produces an output artifact for each output key with state PENDING. However, for an intermediate artifact, this first artifact's state will be REFERENCE. Intermediate artifacts emitted during a component's execution will copy the REFERENCE artifact's attributes. At the end of an execution, the artifact state should remain REFERENCE instead of being changed to LIVE. See also: ml-metadata Artifact.State +type ArtifactState string + +// List of ArtifactState +const ( + ARTIFACTSTATE_UNKNOWN ArtifactState = "UNKNOWN" + ARTIFACTSTATE_PENDING ArtifactState = "PENDING" + ARTIFACTSTATE_LIVE ArtifactState = "LIVE" + ARTIFACTSTATE_MARKED_FOR_DELETION ArtifactState = "MARKED_FOR_DELETION" + ARTIFACTSTATE_DELETED ArtifactState = "DELETED" + ARTIFACTSTATE_ABANDONED ArtifactState = "ABANDONED" + ARTIFACTSTATE_REFERENCE ArtifactState = "REFERENCE" +) + +// All allowed values of ArtifactState enum +var AllowedArtifactStateEnumValues = []ArtifactState{ + "UNKNOWN", + "PENDING", + "LIVE", + "MARKED_FOR_DELETION", + "DELETED", + "ABANDONED", + "REFERENCE", +} + +func (v *ArtifactState) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ArtifactState(value) + for _, existing := range AllowedArtifactStateEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ArtifactState", value) +} + +// NewArtifactStateFromValue returns a pointer to a valid ArtifactState +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewArtifactStateFromValue(v string) (*ArtifactState, error) { + ev := ArtifactState(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ArtifactState: valid values are %v", v, AllowedArtifactStateEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ArtifactState) IsValid() bool { + for _, existing := range AllowedArtifactStateEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to ArtifactState value +func (v ArtifactState) Ptr() *ArtifactState { + return &v +} + +type NullableArtifactState struct { + value *ArtifactState + isSet bool +} + +func (v NullableArtifactState) Get() *ArtifactState { + return v.value +} + +func (v *NullableArtifactState) Set(val *ArtifactState) { + v.value = val + v.isSet = true +} + +func (v NullableArtifactState) IsSet() bool { + return v.isSet +} + +func (v *NullableArtifactState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableArtifactState(val *ArtifactState) *NullableArtifactState { + return &NullableArtifactState{value: val, isSet: true} +} + +func (v NullableArtifactState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableArtifactState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_artifact.go b/internal/model/openapi/model_base_artifact.go new file mode 100644 index 00000000..3908cc5f --- /dev/null +++ b/internal/model/openapi/model_base_artifact.go @@ -0,0 +1,414 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseArtifact type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseArtifact{} + +// BaseArtifact struct for BaseArtifact +type BaseArtifact struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. + Uri *string `json:"uri,omitempty"` + State *ArtifactState `json:"state,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` + ArtifactType string `json:"artifactType"` +} + +// NewBaseArtifact instantiates a new BaseArtifact object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseArtifact(artifactType string) *BaseArtifact { + this := BaseArtifact{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + this.ArtifactType = artifactType + return &this +} + +// NewBaseArtifactWithDefaults instantiates a new BaseArtifact object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseArtifactWithDefaults() *BaseArtifact { + this := BaseArtifact{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseArtifact) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseArtifact) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseArtifact) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseArtifact) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseArtifact) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseArtifact) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetUri returns the Uri field value if set, zero value otherwise. +func (o *BaseArtifact) GetUri() string { + if o == nil || IsNil(o.Uri) { + var ret string + return ret + } + return *o.Uri +} + +// GetUriOk returns a tuple with the Uri field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetUriOk() (*string, bool) { + if o == nil || IsNil(o.Uri) { + return nil, false + } + return o.Uri, true +} + +// HasUri returns a boolean if a field has been set. +func (o *BaseArtifact) HasUri() bool { + if o != nil && !IsNil(o.Uri) { + return true + } + + return false +} + +// SetUri gets a reference to the given string and assigns it to the Uri field. +func (o *BaseArtifact) SetUri(v string) { + o.Uri = &v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *BaseArtifact) GetState() ArtifactState { + if o == nil || IsNil(o.State) { + var ret ArtifactState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetStateOk() (*ArtifactState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *BaseArtifact) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ArtifactState and assigns it to the State field. +func (o *BaseArtifact) SetState(v ArtifactState) { + o.State = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *BaseArtifact) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *BaseArtifact) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *BaseArtifact) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *BaseArtifact) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *BaseArtifact) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *BaseArtifact) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *BaseArtifact) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *BaseArtifact) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *BaseArtifact) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *BaseArtifact) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *BaseArtifact) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *BaseArtifact) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +// GetArtifactType returns the ArtifactType field value +func (o *BaseArtifact) GetArtifactType() string { + if o == nil { + var ret string + return ret + } + + return o.ArtifactType +} + +// GetArtifactTypeOk returns a tuple with the ArtifactType field value +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetArtifactTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ArtifactType, true +} + +// SetArtifactType sets field value +func (o *BaseArtifact) SetArtifactType(v string) { + o.ArtifactType = v +} + +func (o BaseArtifact) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseArtifact) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Uri) { + toSerialize["uri"] = o.Uri + } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + toSerialize["artifactType"] = o.ArtifactType + return toSerialize, nil +} + +type NullableBaseArtifact struct { + value *BaseArtifact + isSet bool +} + +func (v NullableBaseArtifact) Get() *BaseArtifact { + return v.value +} + +func (v *NullableBaseArtifact) Set(val *BaseArtifact) { + v.value = val + v.isSet = true +} + +func (v NullableBaseArtifact) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseArtifact) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseArtifact(val *BaseArtifact) *NullableBaseArtifact { + return &NullableBaseArtifact{value: val, isSet: true} +} + +func (v NullableBaseArtifact) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseArtifact) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_artifact_create.go b/internal/model/openapi/model_base_artifact_create.go new file mode 100644 index 00000000..aa17d8ea --- /dev/null +++ b/internal/model/openapi/model_base_artifact_create.go @@ -0,0 +1,276 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseArtifactCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseArtifactCreate{} + +// BaseArtifactCreate struct for BaseArtifactCreate +type BaseArtifactCreate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. + Uri *string `json:"uri,omitempty"` + State *ArtifactState `json:"state,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` +} + +// NewBaseArtifactCreate instantiates a new BaseArtifactCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseArtifactCreate() *BaseArtifactCreate { + this := BaseArtifactCreate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// NewBaseArtifactCreateWithDefaults instantiates a new BaseArtifactCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseArtifactCreateWithDefaults() *BaseArtifactCreate { + this := BaseArtifactCreate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseArtifactCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseArtifactCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseArtifactCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseArtifactCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseArtifactCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseArtifactCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetUri returns the Uri field value if set, zero value otherwise. +func (o *BaseArtifactCreate) GetUri() string { + if o == nil || IsNil(o.Uri) { + var ret string + return ret + } + return *o.Uri +} + +// GetUriOk returns a tuple with the Uri field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactCreate) GetUriOk() (*string, bool) { + if o == nil || IsNil(o.Uri) { + return nil, false + } + return o.Uri, true +} + +// HasUri returns a boolean if a field has been set. +func (o *BaseArtifactCreate) HasUri() bool { + if o != nil && !IsNil(o.Uri) { + return true + } + + return false +} + +// SetUri gets a reference to the given string and assigns it to the Uri field. +func (o *BaseArtifactCreate) SetUri(v string) { + o.Uri = &v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *BaseArtifactCreate) GetState() ArtifactState { + if o == nil || IsNil(o.State) { + var ret ArtifactState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactCreate) GetStateOk() (*ArtifactState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *BaseArtifactCreate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ArtifactState and assigns it to the State field. +func (o *BaseArtifactCreate) SetState(v ArtifactState) { + o.State = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *BaseArtifactCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *BaseArtifactCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *BaseArtifactCreate) SetName(v string) { + o.Name = &v +} + +func (o BaseArtifactCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseArtifactCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Uri) { + toSerialize["uri"] = o.Uri + } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableBaseArtifactCreate struct { + value *BaseArtifactCreate + isSet bool +} + +func (v NullableBaseArtifactCreate) Get() *BaseArtifactCreate { + return v.value +} + +func (v *NullableBaseArtifactCreate) Set(val *BaseArtifactCreate) { + v.value = val + v.isSet = true +} + +func (v NullableBaseArtifactCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseArtifactCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseArtifactCreate(val *BaseArtifactCreate) *NullableBaseArtifactCreate { + return &NullableBaseArtifactCreate{value: val, isSet: true} +} + +func (v NullableBaseArtifactCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseArtifactCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_artifact_update.go b/internal/model/openapi/model_base_artifact_update.go new file mode 100644 index 00000000..dbea5828 --- /dev/null +++ b/internal/model/openapi/model_base_artifact_update.go @@ -0,0 +1,239 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseArtifactUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseArtifactUpdate{} + +// BaseArtifactUpdate struct for BaseArtifactUpdate +type BaseArtifactUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. + Uri *string `json:"uri,omitempty"` + State *ArtifactState `json:"state,omitempty"` +} + +// NewBaseArtifactUpdate instantiates a new BaseArtifactUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseArtifactUpdate() *BaseArtifactUpdate { + this := BaseArtifactUpdate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// NewBaseArtifactUpdateWithDefaults instantiates a new BaseArtifactUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseArtifactUpdateWithDefaults() *BaseArtifactUpdate { + this := BaseArtifactUpdate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseArtifactUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseArtifactUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseArtifactUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseArtifactUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseArtifactUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseArtifactUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetUri returns the Uri field value if set, zero value otherwise. +func (o *BaseArtifactUpdate) GetUri() string { + if o == nil || IsNil(o.Uri) { + var ret string + return ret + } + return *o.Uri +} + +// GetUriOk returns a tuple with the Uri field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactUpdate) GetUriOk() (*string, bool) { + if o == nil || IsNil(o.Uri) { + return nil, false + } + return o.Uri, true +} + +// HasUri returns a boolean if a field has been set. +func (o *BaseArtifactUpdate) HasUri() bool { + if o != nil && !IsNil(o.Uri) { + return true + } + + return false +} + +// SetUri gets a reference to the given string and assigns it to the Uri field. +func (o *BaseArtifactUpdate) SetUri(v string) { + o.Uri = &v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *BaseArtifactUpdate) GetState() ArtifactState { + if o == nil || IsNil(o.State) { + var ret ArtifactState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactUpdate) GetStateOk() (*ArtifactState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *BaseArtifactUpdate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ArtifactState and assigns it to the State field. +func (o *BaseArtifactUpdate) SetState(v ArtifactState) { + o.State = &v +} + +func (o BaseArtifactUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseArtifactUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Uri) { + toSerialize["uri"] = o.Uri + } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + return toSerialize, nil +} + +type NullableBaseArtifactUpdate struct { + value *BaseArtifactUpdate + isSet bool +} + +func (v NullableBaseArtifactUpdate) Get() *BaseArtifactUpdate { + return v.value +} + +func (v *NullableBaseArtifactUpdate) Set(val *BaseArtifactUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableBaseArtifactUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseArtifactUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseArtifactUpdate(val *BaseArtifactUpdate) *NullableBaseArtifactUpdate { + return &NullableBaseArtifactUpdate{value: val, isSet: true} +} + +func (v NullableBaseArtifactUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseArtifactUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_execution.go b/internal/model/openapi/model_base_execution.go new file mode 100644 index 00000000..24a92fed --- /dev/null +++ b/internal/model/openapi/model_base_execution.go @@ -0,0 +1,350 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseExecution type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseExecution{} + +// BaseExecution struct for BaseExecution +type BaseExecution struct { + LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` +} + +// NewBaseExecution instantiates a new BaseExecution object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseExecution() *BaseExecution { + this := BaseExecution{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// NewBaseExecutionWithDefaults instantiates a new BaseExecution object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseExecutionWithDefaults() *BaseExecution { + this := BaseExecution{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// GetLastKnownState returns the LastKnownState field value if set, zero value otherwise. +func (o *BaseExecution) GetLastKnownState() ExecutionState { + if o == nil || IsNil(o.LastKnownState) { + var ret ExecutionState + return ret + } + return *o.LastKnownState +} + +// GetLastKnownStateOk returns a tuple with the LastKnownState field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetLastKnownStateOk() (*ExecutionState, bool) { + if o == nil || IsNil(o.LastKnownState) { + return nil, false + } + return o.LastKnownState, true +} + +// HasLastKnownState returns a boolean if a field has been set. +func (o *BaseExecution) HasLastKnownState() bool { + if o != nil && !IsNil(o.LastKnownState) { + return true + } + + return false +} + +// SetLastKnownState gets a reference to the given ExecutionState and assigns it to the LastKnownState field. +func (o *BaseExecution) SetLastKnownState(v ExecutionState) { + o.LastKnownState = &v +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseExecution) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseExecution) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseExecution) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseExecution) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseExecution) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseExecution) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *BaseExecution) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *BaseExecution) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *BaseExecution) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *BaseExecution) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *BaseExecution) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *BaseExecution) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *BaseExecution) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *BaseExecution) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *BaseExecution) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *BaseExecution) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *BaseExecution) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *BaseExecution) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +func (o BaseExecution) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseExecution) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.LastKnownState) { + toSerialize["lastKnownState"] = o.LastKnownState + } + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + return toSerialize, nil +} + +type NullableBaseExecution struct { + value *BaseExecution + isSet bool +} + +func (v NullableBaseExecution) Get() *BaseExecution { + return v.value +} + +func (v *NullableBaseExecution) Set(val *BaseExecution) { + v.value = val + v.isSet = true +} + +func (v NullableBaseExecution) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseExecution) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseExecution(val *BaseExecution) *NullableBaseExecution { + return &NullableBaseExecution{value: val, isSet: true} +} + +func (v NullableBaseExecution) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseExecution) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_execution_create.go b/internal/model/openapi/model_base_execution_create.go new file mode 100644 index 00000000..51945d99 --- /dev/null +++ b/internal/model/openapi/model_base_execution_create.go @@ -0,0 +1,239 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseExecutionCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseExecutionCreate{} + +// BaseExecutionCreate struct for BaseExecutionCreate +type BaseExecutionCreate struct { + LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` +} + +// NewBaseExecutionCreate instantiates a new BaseExecutionCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseExecutionCreate() *BaseExecutionCreate { + this := BaseExecutionCreate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// NewBaseExecutionCreateWithDefaults instantiates a new BaseExecutionCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseExecutionCreateWithDefaults() *BaseExecutionCreate { + this := BaseExecutionCreate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// GetLastKnownState returns the LastKnownState field value if set, zero value otherwise. +func (o *BaseExecutionCreate) GetLastKnownState() ExecutionState { + if o == nil || IsNil(o.LastKnownState) { + var ret ExecutionState + return ret + } + return *o.LastKnownState +} + +// GetLastKnownStateOk returns a tuple with the LastKnownState field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionCreate) GetLastKnownStateOk() (*ExecutionState, bool) { + if o == nil || IsNil(o.LastKnownState) { + return nil, false + } + return o.LastKnownState, true +} + +// HasLastKnownState returns a boolean if a field has been set. +func (o *BaseExecutionCreate) HasLastKnownState() bool { + if o != nil && !IsNil(o.LastKnownState) { + return true + } + + return false +} + +// SetLastKnownState gets a reference to the given ExecutionState and assigns it to the LastKnownState field. +func (o *BaseExecutionCreate) SetLastKnownState(v ExecutionState) { + o.LastKnownState = &v +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseExecutionCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseExecutionCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseExecutionCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseExecutionCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseExecutionCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseExecutionCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *BaseExecutionCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *BaseExecutionCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *BaseExecutionCreate) SetName(v string) { + o.Name = &v +} + +func (o BaseExecutionCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseExecutionCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.LastKnownState) { + toSerialize["lastKnownState"] = o.LastKnownState + } + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableBaseExecutionCreate struct { + value *BaseExecutionCreate + isSet bool +} + +func (v NullableBaseExecutionCreate) Get() *BaseExecutionCreate { + return v.value +} + +func (v *NullableBaseExecutionCreate) Set(val *BaseExecutionCreate) { + v.value = val + v.isSet = true +} + +func (v NullableBaseExecutionCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseExecutionCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseExecutionCreate(val *BaseExecutionCreate) *NullableBaseExecutionCreate { + return &NullableBaseExecutionCreate{value: val, isSet: true} +} + +func (v NullableBaseExecutionCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseExecutionCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_execution_update.go b/internal/model/openapi/model_base_execution_update.go new file mode 100644 index 00000000..0375043e --- /dev/null +++ b/internal/model/openapi/model_base_execution_update.go @@ -0,0 +1,202 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseExecutionUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseExecutionUpdate{} + +// BaseExecutionUpdate struct for BaseExecutionUpdate +type BaseExecutionUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` +} + +// NewBaseExecutionUpdate instantiates a new BaseExecutionUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseExecutionUpdate() *BaseExecutionUpdate { + this := BaseExecutionUpdate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// NewBaseExecutionUpdateWithDefaults instantiates a new BaseExecutionUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseExecutionUpdateWithDefaults() *BaseExecutionUpdate { + this := BaseExecutionUpdate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseExecutionUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseExecutionUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseExecutionUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseExecutionUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseExecutionUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseExecutionUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetLastKnownState returns the LastKnownState field value if set, zero value otherwise. +func (o *BaseExecutionUpdate) GetLastKnownState() ExecutionState { + if o == nil || IsNil(o.LastKnownState) { + var ret ExecutionState + return ret + } + return *o.LastKnownState +} + +// GetLastKnownStateOk returns a tuple with the LastKnownState field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionUpdate) GetLastKnownStateOk() (*ExecutionState, bool) { + if o == nil || IsNil(o.LastKnownState) { + return nil, false + } + return o.LastKnownState, true +} + +// HasLastKnownState returns a boolean if a field has been set. +func (o *BaseExecutionUpdate) HasLastKnownState() bool { + if o != nil && !IsNil(o.LastKnownState) { + return true + } + + return false +} + +// SetLastKnownState gets a reference to the given ExecutionState and assigns it to the LastKnownState field. +func (o *BaseExecutionUpdate) SetLastKnownState(v ExecutionState) { + o.LastKnownState = &v +} + +func (o BaseExecutionUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseExecutionUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.LastKnownState) { + toSerialize["lastKnownState"] = o.LastKnownState + } + return toSerialize, nil +} + +type NullableBaseExecutionUpdate struct { + value *BaseExecutionUpdate + isSet bool +} + +func (v NullableBaseExecutionUpdate) Get() *BaseExecutionUpdate { + return v.value +} + +func (v *NullableBaseExecutionUpdate) Set(val *BaseExecutionUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableBaseExecutionUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseExecutionUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseExecutionUpdate(val *BaseExecutionUpdate) *NullableBaseExecutionUpdate { + return &NullableBaseExecutionUpdate{value: val, isSet: true} +} + +func (v NullableBaseExecutionUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseExecutionUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_resource.go b/internal/model/openapi/model_base_resource.go new file mode 100644 index 00000000..aa01540a --- /dev/null +++ b/internal/model/openapi/model_base_resource.go @@ -0,0 +1,310 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseResource type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseResource{} + +// BaseResource struct for BaseResource +type BaseResource struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` +} + +// NewBaseResource instantiates a new BaseResource object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseResource() *BaseResource { + this := BaseResource{} + return &this +} + +// NewBaseResourceWithDefaults instantiates a new BaseResource object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseResourceWithDefaults() *BaseResource { + this := BaseResource{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseResource) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResource) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseResource) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseResource) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseResource) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResource) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseResource) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseResource) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *BaseResource) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResource) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *BaseResource) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *BaseResource) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *BaseResource) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResource) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *BaseResource) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *BaseResource) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *BaseResource) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResource) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *BaseResource) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *BaseResource) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *BaseResource) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResource) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *BaseResource) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *BaseResource) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +func (o BaseResource) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseResource) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + return toSerialize, nil +} + +type NullableBaseResource struct { + value *BaseResource + isSet bool +} + +func (v NullableBaseResource) Get() *BaseResource { + return v.value +} + +func (v *NullableBaseResource) Set(val *BaseResource) { + v.value = val + v.isSet = true +} + +func (v NullableBaseResource) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseResource) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseResource(val *BaseResource) *NullableBaseResource { + return &NullableBaseResource{value: val, isSet: true} +} + +func (v NullableBaseResource) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseResource) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_resource_create.go b/internal/model/openapi/model_base_resource_create.go new file mode 100644 index 00000000..493ccd22 --- /dev/null +++ b/internal/model/openapi/model_base_resource_create.go @@ -0,0 +1,199 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseResourceCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseResourceCreate{} + +// BaseResourceCreate struct for BaseResourceCreate +type BaseResourceCreate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` +} + +// NewBaseResourceCreate instantiates a new BaseResourceCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseResourceCreate() *BaseResourceCreate { + this := BaseResourceCreate{} + return &this +} + +// NewBaseResourceCreateWithDefaults instantiates a new BaseResourceCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseResourceCreateWithDefaults() *BaseResourceCreate { + this := BaseResourceCreate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseResourceCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResourceCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseResourceCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseResourceCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseResourceCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResourceCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseResourceCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseResourceCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *BaseResourceCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResourceCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *BaseResourceCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *BaseResourceCreate) SetName(v string) { + o.Name = &v +} + +func (o BaseResourceCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseResourceCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableBaseResourceCreate struct { + value *BaseResourceCreate + isSet bool +} + +func (v NullableBaseResourceCreate) Get() *BaseResourceCreate { + return v.value +} + +func (v *NullableBaseResourceCreate) Set(val *BaseResourceCreate) { + v.value = val + v.isSet = true +} + +func (v NullableBaseResourceCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseResourceCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseResourceCreate(val *BaseResourceCreate) *NullableBaseResourceCreate { + return &NullableBaseResourceCreate{value: val, isSet: true} +} + +func (v NullableBaseResourceCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseResourceCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_resource_list.go b/internal/model/openapi/model_base_resource_list.go new file mode 100644 index 00000000..d438b687 --- /dev/null +++ b/internal/model/openapi/model_base_resource_list.go @@ -0,0 +1,172 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseResourceList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseResourceList{} + +// BaseResourceList struct for BaseResourceList +type BaseResourceList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` +} + +// NewBaseResourceList instantiates a new BaseResourceList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseResourceList(nextPageToken string, pageSize int32, size int32) *BaseResourceList { + this := BaseResourceList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewBaseResourceListWithDefaults instantiates a new BaseResourceList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseResourceListWithDefaults() *BaseResourceList { + this := BaseResourceList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *BaseResourceList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *BaseResourceList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *BaseResourceList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *BaseResourceList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *BaseResourceList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *BaseResourceList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *BaseResourceList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *BaseResourceList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *BaseResourceList) SetSize(v int32) { + o.Size = v +} + +func (o BaseResourceList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseResourceList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + return toSerialize, nil +} + +type NullableBaseResourceList struct { + value *BaseResourceList + isSet bool +} + +func (v NullableBaseResourceList) Get() *BaseResourceList { + return v.value +} + +func (v *NullableBaseResourceList) Set(val *BaseResourceList) { + v.value = val + v.isSet = true +} + +func (v NullableBaseResourceList) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseResourceList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseResourceList(val *BaseResourceList) *NullableBaseResourceList { + return &NullableBaseResourceList{value: val, isSet: true} +} + +func (v NullableBaseResourceList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseResourceList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_base_resource_update.go b/internal/model/openapi/model_base_resource_update.go new file mode 100644 index 00000000..1814f4bb --- /dev/null +++ b/internal/model/openapi/model_base_resource_update.go @@ -0,0 +1,162 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the BaseResourceUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &BaseResourceUpdate{} + +// BaseResourceUpdate struct for BaseResourceUpdate +type BaseResourceUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` +} + +// NewBaseResourceUpdate instantiates a new BaseResourceUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewBaseResourceUpdate() *BaseResourceUpdate { + this := BaseResourceUpdate{} + return &this +} + +// NewBaseResourceUpdateWithDefaults instantiates a new BaseResourceUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewBaseResourceUpdateWithDefaults() *BaseResourceUpdate { + this := BaseResourceUpdate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *BaseResourceUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResourceUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *BaseResourceUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *BaseResourceUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *BaseResourceUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResourceUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *BaseResourceUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *BaseResourceUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +func (o BaseResourceUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o BaseResourceUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + return toSerialize, nil +} + +type NullableBaseResourceUpdate struct { + value *BaseResourceUpdate + isSet bool +} + +func (v NullableBaseResourceUpdate) Get() *BaseResourceUpdate { + return v.value +} + +func (v *NullableBaseResourceUpdate) Set(val *BaseResourceUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableBaseResourceUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableBaseResourceUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBaseResourceUpdate(val *BaseResourceUpdate) *NullableBaseResourceUpdate { + return &NullableBaseResourceUpdate{value: val, isSet: true} +} + +func (v NullableBaseResourceUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBaseResourceUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_error.go b/internal/model/openapi/model_error.go new file mode 100644 index 00000000..2ad91eaf --- /dev/null +++ b/internal/model/openapi/model_error.go @@ -0,0 +1,144 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the Error type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Error{} + +// Error Error code and message. +type Error struct { + // Error code + Code string `json:"code"` + // Error message + Message string `json:"message"` +} + +// NewError instantiates a new Error object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewError(code string, message string) *Error { + this := Error{} + this.Code = code + this.Message = message + return &this +} + +// NewErrorWithDefaults instantiates a new Error object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewErrorWithDefaults() *Error { + this := Error{} + return &this +} + +// GetCode returns the Code field value +func (o *Error) GetCode() string { + if o == nil { + var ret string + return ret + } + + return o.Code +} + +// GetCodeOk returns a tuple with the Code field value +// and a boolean to check if the value has been set. +func (o *Error) GetCodeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Code, true +} + +// SetCode sets field value +func (o *Error) SetCode(v string) { + o.Code = v +} + +// GetMessage returns the Message field value +func (o *Error) GetMessage() string { + if o == nil { + var ret string + return ret + } + + return o.Message +} + +// GetMessageOk returns a tuple with the Message field value +// and a boolean to check if the value has been set. +func (o *Error) GetMessageOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.Message, true +} + +// SetMessage sets field value +func (o *Error) SetMessage(v string) { + o.Message = v +} + +func (o Error) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Error) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["code"] = o.Code + toSerialize["message"] = o.Message + return toSerialize, nil +} + +type NullableError struct { + value *Error + isSet bool +} + +func (v NullableError) Get() *Error { + return v.value +} + +func (v *NullableError) Set(val *Error) { + v.value = val + v.isSet = true +} + +func (v NullableError) IsSet() bool { + return v.isSet +} + +func (v *NullableError) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableError(val *Error) *NullableError { + return &NullableError{value: val, isSet: true} +} + +func (v NullableError) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableError) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_execution_state.go b/internal/model/openapi/model_execution_state.go new file mode 100644 index 00000000..3cc5df20 --- /dev/null +++ b/internal/model/openapi/model_execution_state.go @@ -0,0 +1,120 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// ExecutionState The state of the Execution. The state transitions are NEW -> RUNNING -> COMPLETE | CACHED | FAILED | CANCELED CACHED means the execution is skipped due to cached results. CANCELED means the execution is skipped due to precondition not met. It is different from CACHED in that a CANCELED execution will not have any event associated with it. It is different from FAILED in that there is no unexpected error happened and it is regarded as a normal state. See also: ml-metadata Execution.State +type ExecutionState string + +// List of ExecutionState +const ( + EXECUTIONSTATE_UNKNOWN ExecutionState = "UNKNOWN" + EXECUTIONSTATE_NEW ExecutionState = "NEW" + EXECUTIONSTATE_RUNNING ExecutionState = "RUNNING" + EXECUTIONSTATE_COMPLETE ExecutionState = "COMPLETE" + EXECUTIONSTATE_FAILED ExecutionState = "FAILED" + EXECUTIONSTATE_CACHED ExecutionState = "CACHED" + EXECUTIONSTATE_CANCELED ExecutionState = "CANCELED" +) + +// All allowed values of ExecutionState enum +var AllowedExecutionStateEnumValues = []ExecutionState{ + "UNKNOWN", + "NEW", + "RUNNING", + "COMPLETE", + "FAILED", + "CACHED", + "CANCELED", +} + +func (v *ExecutionState) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ExecutionState(value) + for _, existing := range AllowedExecutionStateEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ExecutionState", value) +} + +// NewExecutionStateFromValue returns a pointer to a valid ExecutionState +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewExecutionStateFromValue(v string) (*ExecutionState, error) { + ev := ExecutionState(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ExecutionState: valid values are %v", v, AllowedExecutionStateEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ExecutionState) IsValid() bool { + for _, existing := range AllowedExecutionStateEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to ExecutionState value +func (v ExecutionState) Ptr() *ExecutionState { + return &v +} + +type NullableExecutionState struct { + value *ExecutionState + isSet bool +} + +func (v NullableExecutionState) Get() *ExecutionState { + return v.value +} + +func (v *NullableExecutionState) Set(val *ExecutionState) { + v.value = val + v.isSet = true +} + +func (v NullableExecutionState) IsSet() bool { + return v.isSet +} + +func (v *NullableExecutionState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableExecutionState(val *ExecutionState) *NullableExecutionState { + return &NullableExecutionState{value: val, isSet: true} +} + +func (v NullableExecutionState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableExecutionState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_inference_service.go b/internal/model/openapi/model_inference_service.go new file mode 100644 index 00000000..1204f8d3 --- /dev/null +++ b/internal/model/openapi/model_inference_service.go @@ -0,0 +1,403 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the InferenceService type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &InferenceService{} + +// InferenceService An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` from a `RegisteredModel` created by Model Serving. +type InferenceService struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` + // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. + ModelVersionId *string `json:"modelVersionId,omitempty"` + // ID of the `RegisteredModel` to serve. + RegisteredModelId string `json:"registeredModelId"` + // ID of the parent `ServingEnvironment` for this `InferenceService` entity. + ServingEnvironmentId string `json:"servingEnvironmentId"` +} + +// NewInferenceService instantiates a new InferenceService object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewInferenceService(registeredModelId string, servingEnvironmentId string) *InferenceService { + this := InferenceService{} + this.RegisteredModelId = registeredModelId + this.ServingEnvironmentId = servingEnvironmentId + return &this +} + +// NewInferenceServiceWithDefaults instantiates a new InferenceService object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewInferenceServiceWithDefaults() *InferenceService { + this := InferenceService{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *InferenceService) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *InferenceService) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *InferenceService) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *InferenceService) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *InferenceService) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *InferenceService) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *InferenceService) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *InferenceService) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *InferenceService) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *InferenceService) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *InferenceService) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *InferenceService) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *InferenceService) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *InferenceService) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *InferenceService) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *InferenceService) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *InferenceService) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *InferenceService) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +// GetModelVersionId returns the ModelVersionId field value if set, zero value otherwise. +func (o *InferenceService) GetModelVersionId() string { + if o == nil || IsNil(o.ModelVersionId) { + var ret string + return ret + } + return *o.ModelVersionId +} + +// GetModelVersionIdOk returns a tuple with the ModelVersionId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetModelVersionIdOk() (*string, bool) { + if o == nil || IsNil(o.ModelVersionId) { + return nil, false + } + return o.ModelVersionId, true +} + +// HasModelVersionId returns a boolean if a field has been set. +func (o *InferenceService) HasModelVersionId() bool { + if o != nil && !IsNil(o.ModelVersionId) { + return true + } + + return false +} + +// SetModelVersionId gets a reference to the given string and assigns it to the ModelVersionId field. +func (o *InferenceService) SetModelVersionId(v string) { + o.ModelVersionId = &v +} + +// GetRegisteredModelId returns the RegisteredModelId field value +func (o *InferenceService) GetRegisteredModelId() string { + if o == nil { + var ret string + return ret + } + + return o.RegisteredModelId +} + +// GetRegisteredModelIdOk returns a tuple with the RegisteredModelId field value +// and a boolean to check if the value has been set. +func (o *InferenceService) GetRegisteredModelIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.RegisteredModelId, true +} + +// SetRegisteredModelId sets field value +func (o *InferenceService) SetRegisteredModelId(v string) { + o.RegisteredModelId = v +} + +// GetServingEnvironmentId returns the ServingEnvironmentId field value +func (o *InferenceService) GetServingEnvironmentId() string { + if o == nil { + var ret string + return ret + } + + return o.ServingEnvironmentId +} + +// GetServingEnvironmentIdOk returns a tuple with the ServingEnvironmentId field value +// and a boolean to check if the value has been set. +func (o *InferenceService) GetServingEnvironmentIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ServingEnvironmentId, true +} + +// SetServingEnvironmentId sets field value +func (o *InferenceService) SetServingEnvironmentId(v string) { + o.ServingEnvironmentId = v +} + +func (o InferenceService) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o InferenceService) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + if !IsNil(o.ModelVersionId) { + toSerialize["modelVersionId"] = o.ModelVersionId + } + toSerialize["registeredModelId"] = o.RegisteredModelId + toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId + return toSerialize, nil +} + +type NullableInferenceService struct { + value *InferenceService + isSet bool +} + +func (v NullableInferenceService) Get() *InferenceService { + return v.value +} + +func (v *NullableInferenceService) Set(val *InferenceService) { + v.value = val + v.isSet = true +} + +func (v NullableInferenceService) IsSet() bool { + return v.isSet +} + +func (v *NullableInferenceService) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInferenceService(val *InferenceService) *NullableInferenceService { + return &NullableInferenceService{value: val, isSet: true} +} + +func (v NullableInferenceService) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInferenceService) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_inference_service_create.go b/internal/model/openapi/model_inference_service_create.go new file mode 100644 index 00000000..fd25b697 --- /dev/null +++ b/internal/model/openapi/model_inference_service_create.go @@ -0,0 +1,292 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the InferenceServiceCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &InferenceServiceCreate{} + +// InferenceServiceCreate An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` from a `RegisteredModel` created by Model Serving. +type InferenceServiceCreate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. + ModelVersionId *string `json:"modelVersionId,omitempty"` + // ID of the `RegisteredModel` to serve. + RegisteredModelId string `json:"registeredModelId"` + // ID of the parent `ServingEnvironment` for this `InferenceService` entity. + ServingEnvironmentId string `json:"servingEnvironmentId"` +} + +// NewInferenceServiceCreate instantiates a new InferenceServiceCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewInferenceServiceCreate(registeredModelId string, servingEnvironmentId string) *InferenceServiceCreate { + this := InferenceServiceCreate{} + this.RegisteredModelId = registeredModelId + this.ServingEnvironmentId = servingEnvironmentId + return &this +} + +// NewInferenceServiceCreateWithDefaults instantiates a new InferenceServiceCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewInferenceServiceCreateWithDefaults() *InferenceServiceCreate { + this := InferenceServiceCreate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *InferenceServiceCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *InferenceServiceCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *InferenceServiceCreate) SetName(v string) { + o.Name = &v +} + +// GetModelVersionId returns the ModelVersionId field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetModelVersionId() string { + if o == nil || IsNil(o.ModelVersionId) { + var ret string + return ret + } + return *o.ModelVersionId +} + +// GetModelVersionIdOk returns a tuple with the ModelVersionId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetModelVersionIdOk() (*string, bool) { + if o == nil || IsNil(o.ModelVersionId) { + return nil, false + } + return o.ModelVersionId, true +} + +// HasModelVersionId returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasModelVersionId() bool { + if o != nil && !IsNil(o.ModelVersionId) { + return true + } + + return false +} + +// SetModelVersionId gets a reference to the given string and assigns it to the ModelVersionId field. +func (o *InferenceServiceCreate) SetModelVersionId(v string) { + o.ModelVersionId = &v +} + +// GetRegisteredModelId returns the RegisteredModelId field value +func (o *InferenceServiceCreate) GetRegisteredModelId() string { + if o == nil { + var ret string + return ret + } + + return o.RegisteredModelId +} + +// GetRegisteredModelIdOk returns a tuple with the RegisteredModelId field value +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetRegisteredModelIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.RegisteredModelId, true +} + +// SetRegisteredModelId sets field value +func (o *InferenceServiceCreate) SetRegisteredModelId(v string) { + o.RegisteredModelId = v +} + +// GetServingEnvironmentId returns the ServingEnvironmentId field value +func (o *InferenceServiceCreate) GetServingEnvironmentId() string { + if o == nil { + var ret string + return ret + } + + return o.ServingEnvironmentId +} + +// GetServingEnvironmentIdOk returns a tuple with the ServingEnvironmentId field value +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetServingEnvironmentIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ServingEnvironmentId, true +} + +// SetServingEnvironmentId sets field value +func (o *InferenceServiceCreate) SetServingEnvironmentId(v string) { + o.ServingEnvironmentId = v +} + +func (o InferenceServiceCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o InferenceServiceCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.ModelVersionId) { + toSerialize["modelVersionId"] = o.ModelVersionId + } + toSerialize["registeredModelId"] = o.RegisteredModelId + toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId + return toSerialize, nil +} + +type NullableInferenceServiceCreate struct { + value *InferenceServiceCreate + isSet bool +} + +func (v NullableInferenceServiceCreate) Get() *InferenceServiceCreate { + return v.value +} + +func (v *NullableInferenceServiceCreate) Set(val *InferenceServiceCreate) { + v.value = val + v.isSet = true +} + +func (v NullableInferenceServiceCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableInferenceServiceCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInferenceServiceCreate(val *InferenceServiceCreate) *NullableInferenceServiceCreate { + return &NullableInferenceServiceCreate{value: val, isSet: true} +} + +func (v NullableInferenceServiceCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInferenceServiceCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_inference_service_list.go b/internal/model/openapi/model_inference_service_list.go new file mode 100644 index 00000000..e016a5f8 --- /dev/null +++ b/internal/model/openapi/model_inference_service_list.go @@ -0,0 +1,209 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the InferenceServiceList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &InferenceServiceList{} + +// InferenceServiceList List of InferenceServices. +type InferenceServiceList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` + // + Items []InferenceService `json:"items,omitempty"` +} + +// NewInferenceServiceList instantiates a new InferenceServiceList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewInferenceServiceList(nextPageToken string, pageSize int32, size int32) *InferenceServiceList { + this := InferenceServiceList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewInferenceServiceListWithDefaults instantiates a new InferenceServiceList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewInferenceServiceListWithDefaults() *InferenceServiceList { + this := InferenceServiceList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *InferenceServiceList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *InferenceServiceList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *InferenceServiceList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *InferenceServiceList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *InferenceServiceList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *InferenceServiceList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *InferenceServiceList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *InferenceServiceList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *InferenceServiceList) SetSize(v int32) { + o.Size = v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *InferenceServiceList) GetItems() []InferenceService { + if o == nil || IsNil(o.Items) { + var ret []InferenceService + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceList) GetItemsOk() ([]InferenceService, bool) { + if o == nil || IsNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *InferenceServiceList) HasItems() bool { + if o != nil && !IsNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []InferenceService and assigns it to the Items field. +func (o *InferenceServiceList) SetItems(v []InferenceService) { + o.Items = v +} + +func (o InferenceServiceList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o InferenceServiceList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + if !IsNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableInferenceServiceList struct { + value *InferenceServiceList + isSet bool +} + +func (v NullableInferenceServiceList) Get() *InferenceServiceList { + return v.value +} + +func (v *NullableInferenceServiceList) Set(val *InferenceServiceList) { + v.value = val + v.isSet = true +} + +func (v NullableInferenceServiceList) IsSet() bool { + return v.isSet +} + +func (v *NullableInferenceServiceList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInferenceServiceList(val *InferenceServiceList) *NullableInferenceServiceList { + return &NullableInferenceServiceList{value: val, isSet: true} +} + +func (v NullableInferenceServiceList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInferenceServiceList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_inference_service_update.go b/internal/model/openapi/model_inference_service_update.go new file mode 100644 index 00000000..31b1d982 --- /dev/null +++ b/internal/model/openapi/model_inference_service_update.go @@ -0,0 +1,199 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the InferenceServiceUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &InferenceServiceUpdate{} + +// InferenceServiceUpdate An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` from a `RegisteredModel` created by Model Serving. +type InferenceServiceUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. + ModelVersionId *string `json:"modelVersionId,omitempty"` +} + +// NewInferenceServiceUpdate instantiates a new InferenceServiceUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewInferenceServiceUpdate() *InferenceServiceUpdate { + this := InferenceServiceUpdate{} + return &this +} + +// NewInferenceServiceUpdateWithDefaults instantiates a new InferenceServiceUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewInferenceServiceUpdateWithDefaults() *InferenceServiceUpdate { + this := InferenceServiceUpdate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *InferenceServiceUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *InferenceServiceUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *InferenceServiceUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *InferenceServiceUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *InferenceServiceUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *InferenceServiceUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetModelVersionId returns the ModelVersionId field value if set, zero value otherwise. +func (o *InferenceServiceUpdate) GetModelVersionId() string { + if o == nil || IsNil(o.ModelVersionId) { + var ret string + return ret + } + return *o.ModelVersionId +} + +// GetModelVersionIdOk returns a tuple with the ModelVersionId field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceUpdate) GetModelVersionIdOk() (*string, bool) { + if o == nil || IsNil(o.ModelVersionId) { + return nil, false + } + return o.ModelVersionId, true +} + +// HasModelVersionId returns a boolean if a field has been set. +func (o *InferenceServiceUpdate) HasModelVersionId() bool { + if o != nil && !IsNil(o.ModelVersionId) { + return true + } + + return false +} + +// SetModelVersionId gets a reference to the given string and assigns it to the ModelVersionId field. +func (o *InferenceServiceUpdate) SetModelVersionId(v string) { + o.ModelVersionId = &v +} + +func (o InferenceServiceUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o InferenceServiceUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.ModelVersionId) { + toSerialize["modelVersionId"] = o.ModelVersionId + } + return toSerialize, nil +} + +type NullableInferenceServiceUpdate struct { + value *InferenceServiceUpdate + isSet bool +} + +func (v NullableInferenceServiceUpdate) Get() *InferenceServiceUpdate { + return v.value +} + +func (v *NullableInferenceServiceUpdate) Set(val *InferenceServiceUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableInferenceServiceUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableInferenceServiceUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInferenceServiceUpdate(val *InferenceServiceUpdate) *NullableInferenceServiceUpdate { + return &NullableInferenceServiceUpdate{value: val, isSet: true} +} + +func (v NullableInferenceServiceUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInferenceServiceUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_metadata_value.go b/internal/model/openapi/model_metadata_value.go new file mode 100644 index 00000000..e2687469 --- /dev/null +++ b/internal/model/openapi/model_metadata_value.go @@ -0,0 +1,265 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// MetadataValue - A value in properties. +type MetadataValue struct { + MetadataValueOneOf *MetadataValueOneOf + MetadataValueOneOf1 *MetadataValueOneOf1 + MetadataValueOneOf2 *MetadataValueOneOf2 + MetadataValueOneOf3 *MetadataValueOneOf3 + MetadataValueOneOf4 *MetadataValueOneOf4 + MetadataValueOneOf5 *MetadataValueOneOf5 +} + +// MetadataValueOneOfAsMetadataValue is a convenience function that returns MetadataValueOneOf wrapped in MetadataValue +func MetadataValueOneOfAsMetadataValue(v *MetadataValueOneOf) MetadataValue { + return MetadataValue{ + MetadataValueOneOf: v, + } +} + +// MetadataValueOneOf1AsMetadataValue is a convenience function that returns MetadataValueOneOf1 wrapped in MetadataValue +func MetadataValueOneOf1AsMetadataValue(v *MetadataValueOneOf1) MetadataValue { + return MetadataValue{ + MetadataValueOneOf1: v, + } +} + +// MetadataValueOneOf2AsMetadataValue is a convenience function that returns MetadataValueOneOf2 wrapped in MetadataValue +func MetadataValueOneOf2AsMetadataValue(v *MetadataValueOneOf2) MetadataValue { + return MetadataValue{ + MetadataValueOneOf2: v, + } +} + +// MetadataValueOneOf3AsMetadataValue is a convenience function that returns MetadataValueOneOf3 wrapped in MetadataValue +func MetadataValueOneOf3AsMetadataValue(v *MetadataValueOneOf3) MetadataValue { + return MetadataValue{ + MetadataValueOneOf3: v, + } +} + +// MetadataValueOneOf4AsMetadataValue is a convenience function that returns MetadataValueOneOf4 wrapped in MetadataValue +func MetadataValueOneOf4AsMetadataValue(v *MetadataValueOneOf4) MetadataValue { + return MetadataValue{ + MetadataValueOneOf4: v, + } +} + +// MetadataValueOneOf5AsMetadataValue is a convenience function that returns MetadataValueOneOf5 wrapped in MetadataValue +func MetadataValueOneOf5AsMetadataValue(v *MetadataValueOneOf5) MetadataValue { + return MetadataValue{ + MetadataValueOneOf5: v, + } +} + +// Unmarshal JSON data into one of the pointers in the struct +func (dst *MetadataValue) UnmarshalJSON(data []byte) error { + var err error + match := 0 + // try to unmarshal data into MetadataValueOneOf + err = json.Unmarshal(data, &dst.MetadataValueOneOf) + if err == nil { + jsonMetadataValueOneOf, _ := json.Marshal(dst.MetadataValueOneOf) + if string(jsonMetadataValueOneOf) == "{}" { // empty struct + dst.MetadataValueOneOf = nil + } else { + match++ + } + } else { + dst.MetadataValueOneOf = nil + } + + // try to unmarshal data into MetadataValueOneOf1 + err = json.Unmarshal(data, &dst.MetadataValueOneOf1) + if err == nil { + jsonMetadataValueOneOf1, _ := json.Marshal(dst.MetadataValueOneOf1) + if string(jsonMetadataValueOneOf1) == "{}" { // empty struct + dst.MetadataValueOneOf1 = nil + } else { + match++ + } + } else { + dst.MetadataValueOneOf1 = nil + } + + // try to unmarshal data into MetadataValueOneOf2 + err = json.Unmarshal(data, &dst.MetadataValueOneOf2) + if err == nil { + jsonMetadataValueOneOf2, _ := json.Marshal(dst.MetadataValueOneOf2) + if string(jsonMetadataValueOneOf2) == "{}" { // empty struct + dst.MetadataValueOneOf2 = nil + } else { + match++ + } + } else { + dst.MetadataValueOneOf2 = nil + } + + // try to unmarshal data into MetadataValueOneOf3 + err = json.Unmarshal(data, &dst.MetadataValueOneOf3) + if err == nil { + jsonMetadataValueOneOf3, _ := json.Marshal(dst.MetadataValueOneOf3) + if string(jsonMetadataValueOneOf3) == "{}" { // empty struct + dst.MetadataValueOneOf3 = nil + } else { + match++ + } + } else { + dst.MetadataValueOneOf3 = nil + } + + // try to unmarshal data into MetadataValueOneOf4 + err = json.Unmarshal(data, &dst.MetadataValueOneOf4) + if err == nil { + jsonMetadataValueOneOf4, _ := json.Marshal(dst.MetadataValueOneOf4) + if string(jsonMetadataValueOneOf4) == "{}" { // empty struct + dst.MetadataValueOneOf4 = nil + } else { + match++ + } + } else { + dst.MetadataValueOneOf4 = nil + } + + // try to unmarshal data into MetadataValueOneOf5 + err = json.Unmarshal(data, &dst.MetadataValueOneOf5) + if err == nil { + jsonMetadataValueOneOf5, _ := json.Marshal(dst.MetadataValueOneOf5) + if string(jsonMetadataValueOneOf5) == "{}" { // empty struct + dst.MetadataValueOneOf5 = nil + } else { + match++ + } + } else { + dst.MetadataValueOneOf5 = nil + } + + if match > 1 { // more than 1 match + // reset to nil + dst.MetadataValueOneOf = nil + dst.MetadataValueOneOf1 = nil + dst.MetadataValueOneOf2 = nil + dst.MetadataValueOneOf3 = nil + dst.MetadataValueOneOf4 = nil + dst.MetadataValueOneOf5 = nil + + return fmt.Errorf("data matches more than one schema in oneOf(MetadataValue)") + } else if match == 1 { + return nil // exactly one match + } else { // no match + return fmt.Errorf("data failed to match schemas in oneOf(MetadataValue)") + } +} + +// Marshal data from the first non-nil pointers in the struct to JSON +func (src MetadataValue) MarshalJSON() ([]byte, error) { + if src.MetadataValueOneOf != nil { + return json.Marshal(&src.MetadataValueOneOf) + } + + if src.MetadataValueOneOf1 != nil { + return json.Marshal(&src.MetadataValueOneOf1) + } + + if src.MetadataValueOneOf2 != nil { + return json.Marshal(&src.MetadataValueOneOf2) + } + + if src.MetadataValueOneOf3 != nil { + return json.Marshal(&src.MetadataValueOneOf3) + } + + if src.MetadataValueOneOf4 != nil { + return json.Marshal(&src.MetadataValueOneOf4) + } + + if src.MetadataValueOneOf5 != nil { + return json.Marshal(&src.MetadataValueOneOf5) + } + + return nil, nil // no data in oneOf schemas +} + +// Get the actual instance +func (obj *MetadataValue) GetActualInstance() interface{} { + if obj == nil { + return nil + } + if obj.MetadataValueOneOf != nil { + return obj.MetadataValueOneOf + } + + if obj.MetadataValueOneOf1 != nil { + return obj.MetadataValueOneOf1 + } + + if obj.MetadataValueOneOf2 != nil { + return obj.MetadataValueOneOf2 + } + + if obj.MetadataValueOneOf3 != nil { + return obj.MetadataValueOneOf3 + } + + if obj.MetadataValueOneOf4 != nil { + return obj.MetadataValueOneOf4 + } + + if obj.MetadataValueOneOf5 != nil { + return obj.MetadataValueOneOf5 + } + + // all schemas are nil + return nil +} + +type NullableMetadataValue struct { + value *MetadataValue + isSet bool +} + +func (v NullableMetadataValue) Get() *MetadataValue { + return v.value +} + +func (v *NullableMetadataValue) Set(val *MetadataValue) { + v.value = val + v.isSet = true +} + +func (v NullableMetadataValue) IsSet() bool { + return v.isSet +} + +func (v *NullableMetadataValue) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableMetadataValue(val *MetadataValue) *NullableMetadataValue { + return &NullableMetadataValue{value: val, isSet: true} +} + +func (v NullableMetadataValue) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableMetadataValue) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_metadata_value_one_of.go b/internal/model/openapi/model_metadata_value_one_of.go new file mode 100644 index 00000000..c9b8615c --- /dev/null +++ b/internal/model/openapi/model_metadata_value_one_of.go @@ -0,0 +1,124 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the MetadataValueOneOf type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataValueOneOf{} + +// MetadataValueOneOf struct for MetadataValueOneOf +type MetadataValueOneOf struct { + IntValue *string `json:"int_value,omitempty"` +} + +// NewMetadataValueOneOf instantiates a new MetadataValueOneOf object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewMetadataValueOneOf() *MetadataValueOneOf { + this := MetadataValueOneOf{} + return &this +} + +// NewMetadataValueOneOfWithDefaults instantiates a new MetadataValueOneOf object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewMetadataValueOneOfWithDefaults() *MetadataValueOneOf { + this := MetadataValueOneOf{} + return &this +} + +// GetIntValue returns the IntValue field value if set, zero value otherwise. +func (o *MetadataValueOneOf) GetIntValue() string { + if o == nil || IsNil(o.IntValue) { + var ret string + return ret + } + return *o.IntValue +} + +// GetIntValueOk returns a tuple with the IntValue field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *MetadataValueOneOf) GetIntValueOk() (*string, bool) { + if o == nil || IsNil(o.IntValue) { + return nil, false + } + return o.IntValue, true +} + +// HasIntValue returns a boolean if a field has been set. +func (o *MetadataValueOneOf) HasIntValue() bool { + if o != nil && !IsNil(o.IntValue) { + return true + } + + return false +} + +// SetIntValue gets a reference to the given string and assigns it to the IntValue field. +func (o *MetadataValueOneOf) SetIntValue(v string) { + o.IntValue = &v +} + +func (o MetadataValueOneOf) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o MetadataValueOneOf) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.IntValue) { + toSerialize["int_value"] = o.IntValue + } + return toSerialize, nil +} + +type NullableMetadataValueOneOf struct { + value *MetadataValueOneOf + isSet bool +} + +func (v NullableMetadataValueOneOf) Get() *MetadataValueOneOf { + return v.value +} + +func (v *NullableMetadataValueOneOf) Set(val *MetadataValueOneOf) { + v.value = val + v.isSet = true +} + +func (v NullableMetadataValueOneOf) IsSet() bool { + return v.isSet +} + +func (v *NullableMetadataValueOneOf) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableMetadataValueOneOf(val *MetadataValueOneOf) *NullableMetadataValueOneOf { + return &NullableMetadataValueOneOf{value: val, isSet: true} +} + +func (v NullableMetadataValueOneOf) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableMetadataValueOneOf) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_metadata_value_one_of_1.go b/internal/model/openapi/model_metadata_value_one_of_1.go new file mode 100644 index 00000000..60d232bd --- /dev/null +++ b/internal/model/openapi/model_metadata_value_one_of_1.go @@ -0,0 +1,124 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the MetadataValueOneOf1 type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataValueOneOf1{} + +// MetadataValueOneOf1 struct for MetadataValueOneOf1 +type MetadataValueOneOf1 struct { + DoubleValue *float64 `json:"double_value,omitempty"` +} + +// NewMetadataValueOneOf1 instantiates a new MetadataValueOneOf1 object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewMetadataValueOneOf1() *MetadataValueOneOf1 { + this := MetadataValueOneOf1{} + return &this +} + +// NewMetadataValueOneOf1WithDefaults instantiates a new MetadataValueOneOf1 object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewMetadataValueOneOf1WithDefaults() *MetadataValueOneOf1 { + this := MetadataValueOneOf1{} + return &this +} + +// GetDoubleValue returns the DoubleValue field value if set, zero value otherwise. +func (o *MetadataValueOneOf1) GetDoubleValue() float64 { + if o == nil || IsNil(o.DoubleValue) { + var ret float64 + return ret + } + return *o.DoubleValue +} + +// GetDoubleValueOk returns a tuple with the DoubleValue field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *MetadataValueOneOf1) GetDoubleValueOk() (*float64, bool) { + if o == nil || IsNil(o.DoubleValue) { + return nil, false + } + return o.DoubleValue, true +} + +// HasDoubleValue returns a boolean if a field has been set. +func (o *MetadataValueOneOf1) HasDoubleValue() bool { + if o != nil && !IsNil(o.DoubleValue) { + return true + } + + return false +} + +// SetDoubleValue gets a reference to the given float64 and assigns it to the DoubleValue field. +func (o *MetadataValueOneOf1) SetDoubleValue(v float64) { + o.DoubleValue = &v +} + +func (o MetadataValueOneOf1) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o MetadataValueOneOf1) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.DoubleValue) { + toSerialize["double_value"] = o.DoubleValue + } + return toSerialize, nil +} + +type NullableMetadataValueOneOf1 struct { + value *MetadataValueOneOf1 + isSet bool +} + +func (v NullableMetadataValueOneOf1) Get() *MetadataValueOneOf1 { + return v.value +} + +func (v *NullableMetadataValueOneOf1) Set(val *MetadataValueOneOf1) { + v.value = val + v.isSet = true +} + +func (v NullableMetadataValueOneOf1) IsSet() bool { + return v.isSet +} + +func (v *NullableMetadataValueOneOf1) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableMetadataValueOneOf1(val *MetadataValueOneOf1) *NullableMetadataValueOneOf1 { + return &NullableMetadataValueOneOf1{value: val, isSet: true} +} + +func (v NullableMetadataValueOneOf1) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableMetadataValueOneOf1) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_metadata_value_one_of_2.go b/internal/model/openapi/model_metadata_value_one_of_2.go new file mode 100644 index 00000000..51a96b9f --- /dev/null +++ b/internal/model/openapi/model_metadata_value_one_of_2.go @@ -0,0 +1,124 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the MetadataValueOneOf2 type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataValueOneOf2{} + +// MetadataValueOneOf2 struct for MetadataValueOneOf2 +type MetadataValueOneOf2 struct { + StringValue *string `json:"string_value,omitempty"` +} + +// NewMetadataValueOneOf2 instantiates a new MetadataValueOneOf2 object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewMetadataValueOneOf2() *MetadataValueOneOf2 { + this := MetadataValueOneOf2{} + return &this +} + +// NewMetadataValueOneOf2WithDefaults instantiates a new MetadataValueOneOf2 object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewMetadataValueOneOf2WithDefaults() *MetadataValueOneOf2 { + this := MetadataValueOneOf2{} + return &this +} + +// GetStringValue returns the StringValue field value if set, zero value otherwise. +func (o *MetadataValueOneOf2) GetStringValue() string { + if o == nil || IsNil(o.StringValue) { + var ret string + return ret + } + return *o.StringValue +} + +// GetStringValueOk returns a tuple with the StringValue field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *MetadataValueOneOf2) GetStringValueOk() (*string, bool) { + if o == nil || IsNil(o.StringValue) { + return nil, false + } + return o.StringValue, true +} + +// HasStringValue returns a boolean if a field has been set. +func (o *MetadataValueOneOf2) HasStringValue() bool { + if o != nil && !IsNil(o.StringValue) { + return true + } + + return false +} + +// SetStringValue gets a reference to the given string and assigns it to the StringValue field. +func (o *MetadataValueOneOf2) SetStringValue(v string) { + o.StringValue = &v +} + +func (o MetadataValueOneOf2) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o MetadataValueOneOf2) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.StringValue) { + toSerialize["string_value"] = o.StringValue + } + return toSerialize, nil +} + +type NullableMetadataValueOneOf2 struct { + value *MetadataValueOneOf2 + isSet bool +} + +func (v NullableMetadataValueOneOf2) Get() *MetadataValueOneOf2 { + return v.value +} + +func (v *NullableMetadataValueOneOf2) Set(val *MetadataValueOneOf2) { + v.value = val + v.isSet = true +} + +func (v NullableMetadataValueOneOf2) IsSet() bool { + return v.isSet +} + +func (v *NullableMetadataValueOneOf2) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableMetadataValueOneOf2(val *MetadataValueOneOf2) *NullableMetadataValueOneOf2 { + return &NullableMetadataValueOneOf2{value: val, isSet: true} +} + +func (v NullableMetadataValueOneOf2) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableMetadataValueOneOf2) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_metadata_value_one_of_3.go b/internal/model/openapi/model_metadata_value_one_of_3.go new file mode 100644 index 00000000..c637edd9 --- /dev/null +++ b/internal/model/openapi/model_metadata_value_one_of_3.go @@ -0,0 +1,125 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the MetadataValueOneOf3 type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataValueOneOf3{} + +// MetadataValueOneOf3 struct for MetadataValueOneOf3 +type MetadataValueOneOf3 struct { + // Base64 encoded bytes for struct value + StructValue *string `json:"struct_value,omitempty"` +} + +// NewMetadataValueOneOf3 instantiates a new MetadataValueOneOf3 object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewMetadataValueOneOf3() *MetadataValueOneOf3 { + this := MetadataValueOneOf3{} + return &this +} + +// NewMetadataValueOneOf3WithDefaults instantiates a new MetadataValueOneOf3 object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewMetadataValueOneOf3WithDefaults() *MetadataValueOneOf3 { + this := MetadataValueOneOf3{} + return &this +} + +// GetStructValue returns the StructValue field value if set, zero value otherwise. +func (o *MetadataValueOneOf3) GetStructValue() string { + if o == nil || IsNil(o.StructValue) { + var ret string + return ret + } + return *o.StructValue +} + +// GetStructValueOk returns a tuple with the StructValue field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *MetadataValueOneOf3) GetStructValueOk() (*string, bool) { + if o == nil || IsNil(o.StructValue) { + return nil, false + } + return o.StructValue, true +} + +// HasStructValue returns a boolean if a field has been set. +func (o *MetadataValueOneOf3) HasStructValue() bool { + if o != nil && !IsNil(o.StructValue) { + return true + } + + return false +} + +// SetStructValue gets a reference to the given string and assigns it to the StructValue field. +func (o *MetadataValueOneOf3) SetStructValue(v string) { + o.StructValue = &v +} + +func (o MetadataValueOneOf3) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o MetadataValueOneOf3) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.StructValue) { + toSerialize["struct_value"] = o.StructValue + } + return toSerialize, nil +} + +type NullableMetadataValueOneOf3 struct { + value *MetadataValueOneOf3 + isSet bool +} + +func (v NullableMetadataValueOneOf3) Get() *MetadataValueOneOf3 { + return v.value +} + +func (v *NullableMetadataValueOneOf3) Set(val *MetadataValueOneOf3) { + v.value = val + v.isSet = true +} + +func (v NullableMetadataValueOneOf3) IsSet() bool { + return v.isSet +} + +func (v *NullableMetadataValueOneOf3) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableMetadataValueOneOf3(val *MetadataValueOneOf3) *NullableMetadataValueOneOf3 { + return &NullableMetadataValueOneOf3{value: val, isSet: true} +} + +func (v NullableMetadataValueOneOf3) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableMetadataValueOneOf3) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_metadata_value_one_of_4.go b/internal/model/openapi/model_metadata_value_one_of_4.go new file mode 100644 index 00000000..622f9810 --- /dev/null +++ b/internal/model/openapi/model_metadata_value_one_of_4.go @@ -0,0 +1,162 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the MetadataValueOneOf4 type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataValueOneOf4{} + +// MetadataValueOneOf4 struct for MetadataValueOneOf4 +type MetadataValueOneOf4 struct { + // url describing proto value + Type *string `json:"type,omitempty"` + // Base64 encoded bytes for proto value + ProtoValue *string `json:"proto_value,omitempty"` +} + +// NewMetadataValueOneOf4 instantiates a new MetadataValueOneOf4 object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewMetadataValueOneOf4() *MetadataValueOneOf4 { + this := MetadataValueOneOf4{} + return &this +} + +// NewMetadataValueOneOf4WithDefaults instantiates a new MetadataValueOneOf4 object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewMetadataValueOneOf4WithDefaults() *MetadataValueOneOf4 { + this := MetadataValueOneOf4{} + return &this +} + +// GetType returns the Type field value if set, zero value otherwise. +func (o *MetadataValueOneOf4) GetType() string { + if o == nil || IsNil(o.Type) { + var ret string + return ret + } + return *o.Type +} + +// GetTypeOk returns a tuple with the Type field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *MetadataValueOneOf4) GetTypeOk() (*string, bool) { + if o == nil || IsNil(o.Type) { + return nil, false + } + return o.Type, true +} + +// HasType returns a boolean if a field has been set. +func (o *MetadataValueOneOf4) HasType() bool { + if o != nil && !IsNil(o.Type) { + return true + } + + return false +} + +// SetType gets a reference to the given string and assigns it to the Type field. +func (o *MetadataValueOneOf4) SetType(v string) { + o.Type = &v +} + +// GetProtoValue returns the ProtoValue field value if set, zero value otherwise. +func (o *MetadataValueOneOf4) GetProtoValue() string { + if o == nil || IsNil(o.ProtoValue) { + var ret string + return ret + } + return *o.ProtoValue +} + +// GetProtoValueOk returns a tuple with the ProtoValue field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *MetadataValueOneOf4) GetProtoValueOk() (*string, bool) { + if o == nil || IsNil(o.ProtoValue) { + return nil, false + } + return o.ProtoValue, true +} + +// HasProtoValue returns a boolean if a field has been set. +func (o *MetadataValueOneOf4) HasProtoValue() bool { + if o != nil && !IsNil(o.ProtoValue) { + return true + } + + return false +} + +// SetProtoValue gets a reference to the given string and assigns it to the ProtoValue field. +func (o *MetadataValueOneOf4) SetProtoValue(v string) { + o.ProtoValue = &v +} + +func (o MetadataValueOneOf4) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o MetadataValueOneOf4) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Type) { + toSerialize["type"] = o.Type + } + if !IsNil(o.ProtoValue) { + toSerialize["proto_value"] = o.ProtoValue + } + return toSerialize, nil +} + +type NullableMetadataValueOneOf4 struct { + value *MetadataValueOneOf4 + isSet bool +} + +func (v NullableMetadataValueOneOf4) Get() *MetadataValueOneOf4 { + return v.value +} + +func (v *NullableMetadataValueOneOf4) Set(val *MetadataValueOneOf4) { + v.value = val + v.isSet = true +} + +func (v NullableMetadataValueOneOf4) IsSet() bool { + return v.isSet +} + +func (v *NullableMetadataValueOneOf4) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableMetadataValueOneOf4(val *MetadataValueOneOf4) *NullableMetadataValueOneOf4 { + return &NullableMetadataValueOneOf4{value: val, isSet: true} +} + +func (v NullableMetadataValueOneOf4) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableMetadataValueOneOf4) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_metadata_value_one_of_5.go b/internal/model/openapi/model_metadata_value_one_of_5.go new file mode 100644 index 00000000..745320ed --- /dev/null +++ b/internal/model/openapi/model_metadata_value_one_of_5.go @@ -0,0 +1,124 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the MetadataValueOneOf5 type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataValueOneOf5{} + +// MetadataValueOneOf5 struct for MetadataValueOneOf5 +type MetadataValueOneOf5 struct { + BoolValue *bool `json:"bool_value,omitempty"` +} + +// NewMetadataValueOneOf5 instantiates a new MetadataValueOneOf5 object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewMetadataValueOneOf5() *MetadataValueOneOf5 { + this := MetadataValueOneOf5{} + return &this +} + +// NewMetadataValueOneOf5WithDefaults instantiates a new MetadataValueOneOf5 object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewMetadataValueOneOf5WithDefaults() *MetadataValueOneOf5 { + this := MetadataValueOneOf5{} + return &this +} + +// GetBoolValue returns the BoolValue field value if set, zero value otherwise. +func (o *MetadataValueOneOf5) GetBoolValue() bool { + if o == nil || IsNil(o.BoolValue) { + var ret bool + return ret + } + return *o.BoolValue +} + +// GetBoolValueOk returns a tuple with the BoolValue field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *MetadataValueOneOf5) GetBoolValueOk() (*bool, bool) { + if o == nil || IsNil(o.BoolValue) { + return nil, false + } + return o.BoolValue, true +} + +// HasBoolValue returns a boolean if a field has been set. +func (o *MetadataValueOneOf5) HasBoolValue() bool { + if o != nil && !IsNil(o.BoolValue) { + return true + } + + return false +} + +// SetBoolValue gets a reference to the given bool and assigns it to the BoolValue field. +func (o *MetadataValueOneOf5) SetBoolValue(v bool) { + o.BoolValue = &v +} + +func (o MetadataValueOneOf5) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o MetadataValueOneOf5) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.BoolValue) { + toSerialize["bool_value"] = o.BoolValue + } + return toSerialize, nil +} + +type NullableMetadataValueOneOf5 struct { + value *MetadataValueOneOf5 + isSet bool +} + +func (v NullableMetadataValueOneOf5) Get() *MetadataValueOneOf5 { + return v.value +} + +func (v *NullableMetadataValueOneOf5) Set(val *MetadataValueOneOf5) { + v.value = val + v.isSet = true +} + +func (v NullableMetadataValueOneOf5) IsSet() bool { + return v.isSet +} + +func (v *NullableMetadataValueOneOf5) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableMetadataValueOneOf5(val *MetadataValueOneOf5) *NullableMetadataValueOneOf5 { + return &NullableMetadataValueOneOf5{value: val, isSet: true} +} + +func (v NullableMetadataValueOneOf5) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableMetadataValueOneOf5) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_artifact.go b/internal/model/openapi/model_model_artifact.go new file mode 100644 index 00000000..3b064d1b --- /dev/null +++ b/internal/model/openapi/model_model_artifact.go @@ -0,0 +1,636 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelArtifact type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelArtifact{} + +// ModelArtifact An ML model artifact. +type ModelArtifact struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. + Uri *string `json:"uri,omitempty"` + State *ArtifactState `json:"state,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` + ArtifactType string `json:"artifactType"` + // Name of the model format. + ModelFormatName *string `json:"modelFormatName,omitempty"` + // Model runtime. + Runtime *string `json:"runtime,omitempty"` + // Storage secret name. + StorageKey *string `json:"storageKey,omitempty"` + // Path for model in storage provided by `storageKey`. + StoragePath *string `json:"storagePath,omitempty"` + // Version of the model format. + ModelFormatVersion *string `json:"modelFormatVersion,omitempty"` + // Name of the service account with storage secret. + ServiceAccountName *string `json:"serviceAccountName,omitempty"` +} + +// NewModelArtifact instantiates a new ModelArtifact object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelArtifact(artifactType string) *ModelArtifact { + this := ModelArtifact{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + this.ArtifactType = artifactType + return &this +} + +// NewModelArtifactWithDefaults instantiates a new ModelArtifact object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelArtifactWithDefaults() *ModelArtifact { + this := ModelArtifact{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ModelArtifact) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ModelArtifact) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ModelArtifact) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ModelArtifact) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ModelArtifact) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ModelArtifact) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetUri returns the Uri field value if set, zero value otherwise. +func (o *ModelArtifact) GetUri() string { + if o == nil || IsNil(o.Uri) { + var ret string + return ret + } + return *o.Uri +} + +// GetUriOk returns a tuple with the Uri field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetUriOk() (*string, bool) { + if o == nil || IsNil(o.Uri) { + return nil, false + } + return o.Uri, true +} + +// HasUri returns a boolean if a field has been set. +func (o *ModelArtifact) HasUri() bool { + if o != nil && !IsNil(o.Uri) { + return true + } + + return false +} + +// SetUri gets a reference to the given string and assigns it to the Uri field. +func (o *ModelArtifact) SetUri(v string) { + o.Uri = &v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *ModelArtifact) GetState() ArtifactState { + if o == nil || IsNil(o.State) { + var ret ArtifactState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetStateOk() (*ArtifactState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *ModelArtifact) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ArtifactState and assigns it to the State field. +func (o *ModelArtifact) SetState(v ArtifactState) { + o.State = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ModelArtifact) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ModelArtifact) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ModelArtifact) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ModelArtifact) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ModelArtifact) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ModelArtifact) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ModelArtifact) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ModelArtifact) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *ModelArtifact) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ModelArtifact) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ModelArtifact) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *ModelArtifact) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +// GetArtifactType returns the ArtifactType field value +func (o *ModelArtifact) GetArtifactType() string { + if o == nil { + var ret string + return ret + } + + return o.ArtifactType +} + +// GetArtifactTypeOk returns a tuple with the ArtifactType field value +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetArtifactTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ArtifactType, true +} + +// SetArtifactType sets field value +func (o *ModelArtifact) SetArtifactType(v string) { + o.ArtifactType = v +} + +// GetModelFormatName returns the ModelFormatName field value if set, zero value otherwise. +func (o *ModelArtifact) GetModelFormatName() string { + if o == nil || IsNil(o.ModelFormatName) { + var ret string + return ret + } + return *o.ModelFormatName +} + +// GetModelFormatNameOk returns a tuple with the ModelFormatName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetModelFormatNameOk() (*string, bool) { + if o == nil || IsNil(o.ModelFormatName) { + return nil, false + } + return o.ModelFormatName, true +} + +// HasModelFormatName returns a boolean if a field has been set. +func (o *ModelArtifact) HasModelFormatName() bool { + if o != nil && !IsNil(o.ModelFormatName) { + return true + } + + return false +} + +// SetModelFormatName gets a reference to the given string and assigns it to the ModelFormatName field. +func (o *ModelArtifact) SetModelFormatName(v string) { + o.ModelFormatName = &v +} + +// GetRuntime returns the Runtime field value if set, zero value otherwise. +func (o *ModelArtifact) GetRuntime() string { + if o == nil || IsNil(o.Runtime) { + var ret string + return ret + } + return *o.Runtime +} + +// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetRuntimeOk() (*string, bool) { + if o == nil || IsNil(o.Runtime) { + return nil, false + } + return o.Runtime, true +} + +// HasRuntime returns a boolean if a field has been set. +func (o *ModelArtifact) HasRuntime() bool { + if o != nil && !IsNil(o.Runtime) { + return true + } + + return false +} + +// SetRuntime gets a reference to the given string and assigns it to the Runtime field. +func (o *ModelArtifact) SetRuntime(v string) { + o.Runtime = &v +} + +// GetStorageKey returns the StorageKey field value if set, zero value otherwise. +func (o *ModelArtifact) GetStorageKey() string { + if o == nil || IsNil(o.StorageKey) { + var ret string + return ret + } + return *o.StorageKey +} + +// GetStorageKeyOk returns a tuple with the StorageKey field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetStorageKeyOk() (*string, bool) { + if o == nil || IsNil(o.StorageKey) { + return nil, false + } + return o.StorageKey, true +} + +// HasStorageKey returns a boolean if a field has been set. +func (o *ModelArtifact) HasStorageKey() bool { + if o != nil && !IsNil(o.StorageKey) { + return true + } + + return false +} + +// SetStorageKey gets a reference to the given string and assigns it to the StorageKey field. +func (o *ModelArtifact) SetStorageKey(v string) { + o.StorageKey = &v +} + +// GetStoragePath returns the StoragePath field value if set, zero value otherwise. +func (o *ModelArtifact) GetStoragePath() string { + if o == nil || IsNil(o.StoragePath) { + var ret string + return ret + } + return *o.StoragePath +} + +// GetStoragePathOk returns a tuple with the StoragePath field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetStoragePathOk() (*string, bool) { + if o == nil || IsNil(o.StoragePath) { + return nil, false + } + return o.StoragePath, true +} + +// HasStoragePath returns a boolean if a field has been set. +func (o *ModelArtifact) HasStoragePath() bool { + if o != nil && !IsNil(o.StoragePath) { + return true + } + + return false +} + +// SetStoragePath gets a reference to the given string and assigns it to the StoragePath field. +func (o *ModelArtifact) SetStoragePath(v string) { + o.StoragePath = &v +} + +// GetModelFormatVersion returns the ModelFormatVersion field value if set, zero value otherwise. +func (o *ModelArtifact) GetModelFormatVersion() string { + if o == nil || IsNil(o.ModelFormatVersion) { + var ret string + return ret + } + return *o.ModelFormatVersion +} + +// GetModelFormatVersionOk returns a tuple with the ModelFormatVersion field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetModelFormatVersionOk() (*string, bool) { + if o == nil || IsNil(o.ModelFormatVersion) { + return nil, false + } + return o.ModelFormatVersion, true +} + +// HasModelFormatVersion returns a boolean if a field has been set. +func (o *ModelArtifact) HasModelFormatVersion() bool { + if o != nil && !IsNil(o.ModelFormatVersion) { + return true + } + + return false +} + +// SetModelFormatVersion gets a reference to the given string and assigns it to the ModelFormatVersion field. +func (o *ModelArtifact) SetModelFormatVersion(v string) { + o.ModelFormatVersion = &v +} + +// GetServiceAccountName returns the ServiceAccountName field value if set, zero value otherwise. +func (o *ModelArtifact) GetServiceAccountName() string { + if o == nil || IsNil(o.ServiceAccountName) { + var ret string + return ret + } + return *o.ServiceAccountName +} + +// GetServiceAccountNameOk returns a tuple with the ServiceAccountName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetServiceAccountNameOk() (*string, bool) { + if o == nil || IsNil(o.ServiceAccountName) { + return nil, false + } + return o.ServiceAccountName, true +} + +// HasServiceAccountName returns a boolean if a field has been set. +func (o *ModelArtifact) HasServiceAccountName() bool { + if o != nil && !IsNil(o.ServiceAccountName) { + return true + } + + return false +} + +// SetServiceAccountName gets a reference to the given string and assigns it to the ServiceAccountName field. +func (o *ModelArtifact) SetServiceAccountName(v string) { + o.ServiceAccountName = &v +} + +func (o ModelArtifact) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelArtifact) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Uri) { + toSerialize["uri"] = o.Uri + } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + toSerialize["artifactType"] = o.ArtifactType + if !IsNil(o.ModelFormatName) { + toSerialize["modelFormatName"] = o.ModelFormatName + } + if !IsNil(o.Runtime) { + toSerialize["runtime"] = o.Runtime + } + if !IsNil(o.StorageKey) { + toSerialize["storageKey"] = o.StorageKey + } + if !IsNil(o.StoragePath) { + toSerialize["storagePath"] = o.StoragePath + } + if !IsNil(o.ModelFormatVersion) { + toSerialize["modelFormatVersion"] = o.ModelFormatVersion + } + if !IsNil(o.ServiceAccountName) { + toSerialize["serviceAccountName"] = o.ServiceAccountName + } + return toSerialize, nil +} + +type NullableModelArtifact struct { + value *ModelArtifact + isSet bool +} + +func (v NullableModelArtifact) Get() *ModelArtifact { + return v.value +} + +func (v *NullableModelArtifact) Set(val *ModelArtifact) { + v.value = val + v.isSet = true +} + +func (v NullableModelArtifact) IsSet() bool { + return v.isSet +} + +func (v *NullableModelArtifact) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelArtifact(val *ModelArtifact) *NullableModelArtifact { + return &NullableModelArtifact{value: val, isSet: true} +} + +func (v NullableModelArtifact) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelArtifact) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_artifact_create.go b/internal/model/openapi/model_model_artifact_create.go new file mode 100644 index 00000000..cfeb5c0f --- /dev/null +++ b/internal/model/openapi/model_model_artifact_create.go @@ -0,0 +1,498 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelArtifactCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelArtifactCreate{} + +// ModelArtifactCreate An ML model artifact. +type ModelArtifactCreate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. + Uri *string `json:"uri,omitempty"` + State *ArtifactState `json:"state,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Name of the model format. + ModelFormatName *string `json:"modelFormatName,omitempty"` + // Model runtime. + Runtime *string `json:"runtime,omitempty"` + // Storage secret name. + StorageKey *string `json:"storageKey,omitempty"` + // Path for model in storage provided by `storageKey`. + StoragePath *string `json:"storagePath,omitempty"` + // Version of the model format. + ModelFormatVersion *string `json:"modelFormatVersion,omitempty"` + // Name of the service account with storage secret. + ServiceAccountName *string `json:"serviceAccountName,omitempty"` +} + +// NewModelArtifactCreate instantiates a new ModelArtifactCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelArtifactCreate() *ModelArtifactCreate { + this := ModelArtifactCreate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// NewModelArtifactCreateWithDefaults instantiates a new ModelArtifactCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelArtifactCreateWithDefaults() *ModelArtifactCreate { + this := ModelArtifactCreate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ModelArtifactCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ModelArtifactCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetUri returns the Uri field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetUri() string { + if o == nil || IsNil(o.Uri) { + var ret string + return ret + } + return *o.Uri +} + +// GetUriOk returns a tuple with the Uri field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetUriOk() (*string, bool) { + if o == nil || IsNil(o.Uri) { + return nil, false + } + return o.Uri, true +} + +// HasUri returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasUri() bool { + if o != nil && !IsNil(o.Uri) { + return true + } + + return false +} + +// SetUri gets a reference to the given string and assigns it to the Uri field. +func (o *ModelArtifactCreate) SetUri(v string) { + o.Uri = &v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetState() ArtifactState { + if o == nil || IsNil(o.State) { + var ret ArtifactState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetStateOk() (*ArtifactState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ArtifactState and assigns it to the State field. +func (o *ModelArtifactCreate) SetState(v ArtifactState) { + o.State = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ModelArtifactCreate) SetName(v string) { + o.Name = &v +} + +// GetModelFormatName returns the ModelFormatName field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetModelFormatName() string { + if o == nil || IsNil(o.ModelFormatName) { + var ret string + return ret + } + return *o.ModelFormatName +} + +// GetModelFormatNameOk returns a tuple with the ModelFormatName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetModelFormatNameOk() (*string, bool) { + if o == nil || IsNil(o.ModelFormatName) { + return nil, false + } + return o.ModelFormatName, true +} + +// HasModelFormatName returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasModelFormatName() bool { + if o != nil && !IsNil(o.ModelFormatName) { + return true + } + + return false +} + +// SetModelFormatName gets a reference to the given string and assigns it to the ModelFormatName field. +func (o *ModelArtifactCreate) SetModelFormatName(v string) { + o.ModelFormatName = &v +} + +// GetRuntime returns the Runtime field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetRuntime() string { + if o == nil || IsNil(o.Runtime) { + var ret string + return ret + } + return *o.Runtime +} + +// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetRuntimeOk() (*string, bool) { + if o == nil || IsNil(o.Runtime) { + return nil, false + } + return o.Runtime, true +} + +// HasRuntime returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasRuntime() bool { + if o != nil && !IsNil(o.Runtime) { + return true + } + + return false +} + +// SetRuntime gets a reference to the given string and assigns it to the Runtime field. +func (o *ModelArtifactCreate) SetRuntime(v string) { + o.Runtime = &v +} + +// GetStorageKey returns the StorageKey field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetStorageKey() string { + if o == nil || IsNil(o.StorageKey) { + var ret string + return ret + } + return *o.StorageKey +} + +// GetStorageKeyOk returns a tuple with the StorageKey field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetStorageKeyOk() (*string, bool) { + if o == nil || IsNil(o.StorageKey) { + return nil, false + } + return o.StorageKey, true +} + +// HasStorageKey returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasStorageKey() bool { + if o != nil && !IsNil(o.StorageKey) { + return true + } + + return false +} + +// SetStorageKey gets a reference to the given string and assigns it to the StorageKey field. +func (o *ModelArtifactCreate) SetStorageKey(v string) { + o.StorageKey = &v +} + +// GetStoragePath returns the StoragePath field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetStoragePath() string { + if o == nil || IsNil(o.StoragePath) { + var ret string + return ret + } + return *o.StoragePath +} + +// GetStoragePathOk returns a tuple with the StoragePath field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetStoragePathOk() (*string, bool) { + if o == nil || IsNil(o.StoragePath) { + return nil, false + } + return o.StoragePath, true +} + +// HasStoragePath returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasStoragePath() bool { + if o != nil && !IsNil(o.StoragePath) { + return true + } + + return false +} + +// SetStoragePath gets a reference to the given string and assigns it to the StoragePath field. +func (o *ModelArtifactCreate) SetStoragePath(v string) { + o.StoragePath = &v +} + +// GetModelFormatVersion returns the ModelFormatVersion field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetModelFormatVersion() string { + if o == nil || IsNil(o.ModelFormatVersion) { + var ret string + return ret + } + return *o.ModelFormatVersion +} + +// GetModelFormatVersionOk returns a tuple with the ModelFormatVersion field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetModelFormatVersionOk() (*string, bool) { + if o == nil || IsNil(o.ModelFormatVersion) { + return nil, false + } + return o.ModelFormatVersion, true +} + +// HasModelFormatVersion returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasModelFormatVersion() bool { + if o != nil && !IsNil(o.ModelFormatVersion) { + return true + } + + return false +} + +// SetModelFormatVersion gets a reference to the given string and assigns it to the ModelFormatVersion field. +func (o *ModelArtifactCreate) SetModelFormatVersion(v string) { + o.ModelFormatVersion = &v +} + +// GetServiceAccountName returns the ServiceAccountName field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetServiceAccountName() string { + if o == nil || IsNil(o.ServiceAccountName) { + var ret string + return ret + } + return *o.ServiceAccountName +} + +// GetServiceAccountNameOk returns a tuple with the ServiceAccountName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetServiceAccountNameOk() (*string, bool) { + if o == nil || IsNil(o.ServiceAccountName) { + return nil, false + } + return o.ServiceAccountName, true +} + +// HasServiceAccountName returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasServiceAccountName() bool { + if o != nil && !IsNil(o.ServiceAccountName) { + return true + } + + return false +} + +// SetServiceAccountName gets a reference to the given string and assigns it to the ServiceAccountName field. +func (o *ModelArtifactCreate) SetServiceAccountName(v string) { + o.ServiceAccountName = &v +} + +func (o ModelArtifactCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelArtifactCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Uri) { + toSerialize["uri"] = o.Uri + } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.ModelFormatName) { + toSerialize["modelFormatName"] = o.ModelFormatName + } + if !IsNil(o.Runtime) { + toSerialize["runtime"] = o.Runtime + } + if !IsNil(o.StorageKey) { + toSerialize["storageKey"] = o.StorageKey + } + if !IsNil(o.StoragePath) { + toSerialize["storagePath"] = o.StoragePath + } + if !IsNil(o.ModelFormatVersion) { + toSerialize["modelFormatVersion"] = o.ModelFormatVersion + } + if !IsNil(o.ServiceAccountName) { + toSerialize["serviceAccountName"] = o.ServiceAccountName + } + return toSerialize, nil +} + +type NullableModelArtifactCreate struct { + value *ModelArtifactCreate + isSet bool +} + +func (v NullableModelArtifactCreate) Get() *ModelArtifactCreate { + return v.value +} + +func (v *NullableModelArtifactCreate) Set(val *ModelArtifactCreate) { + v.value = val + v.isSet = true +} + +func (v NullableModelArtifactCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableModelArtifactCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelArtifactCreate(val *ModelArtifactCreate) *NullableModelArtifactCreate { + return &NullableModelArtifactCreate{value: val, isSet: true} +} + +func (v NullableModelArtifactCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelArtifactCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_artifact_list.go b/internal/model/openapi/model_model_artifact_list.go new file mode 100644 index 00000000..93da4e4b --- /dev/null +++ b/internal/model/openapi/model_model_artifact_list.go @@ -0,0 +1,209 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelArtifactList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelArtifactList{} + +// ModelArtifactList List of ModelArtifact entities. +type ModelArtifactList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` + // Array of `ModelArtifact` entities. + Items []ModelArtifact `json:"items,omitempty"` +} + +// NewModelArtifactList instantiates a new ModelArtifactList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelArtifactList(nextPageToken string, pageSize int32, size int32) *ModelArtifactList { + this := ModelArtifactList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewModelArtifactListWithDefaults instantiates a new ModelArtifactList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelArtifactListWithDefaults() *ModelArtifactList { + this := ModelArtifactList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *ModelArtifactList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *ModelArtifactList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *ModelArtifactList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *ModelArtifactList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *ModelArtifactList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *ModelArtifactList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *ModelArtifactList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *ModelArtifactList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *ModelArtifactList) SetSize(v int32) { + o.Size = v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *ModelArtifactList) GetItems() []ModelArtifact { + if o == nil || IsNil(o.Items) { + var ret []ModelArtifact + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactList) GetItemsOk() ([]ModelArtifact, bool) { + if o == nil || IsNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *ModelArtifactList) HasItems() bool { + if o != nil && !IsNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []ModelArtifact and assigns it to the Items field. +func (o *ModelArtifactList) SetItems(v []ModelArtifact) { + o.Items = v +} + +func (o ModelArtifactList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelArtifactList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + if !IsNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableModelArtifactList struct { + value *ModelArtifactList + isSet bool +} + +func (v NullableModelArtifactList) Get() *ModelArtifactList { + return v.value +} + +func (v *NullableModelArtifactList) Set(val *ModelArtifactList) { + v.value = val + v.isSet = true +} + +func (v NullableModelArtifactList) IsSet() bool { + return v.isSet +} + +func (v *NullableModelArtifactList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelArtifactList(val *ModelArtifactList) *NullableModelArtifactList { + return &NullableModelArtifactList{value: val, isSet: true} +} + +func (v NullableModelArtifactList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelArtifactList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_artifact_update.go b/internal/model/openapi/model_model_artifact_update.go new file mode 100644 index 00000000..2cda6724 --- /dev/null +++ b/internal/model/openapi/model_model_artifact_update.go @@ -0,0 +1,461 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelArtifactUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelArtifactUpdate{} + +// ModelArtifactUpdate An ML model artifact. +type ModelArtifactUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. + Uri *string `json:"uri,omitempty"` + State *ArtifactState `json:"state,omitempty"` + // Name of the model format. + ModelFormatName *string `json:"modelFormatName,omitempty"` + // Model runtime. + Runtime *string `json:"runtime,omitempty"` + // Storage secret name. + StorageKey *string `json:"storageKey,omitempty"` + // Path for model in storage provided by `storageKey`. + StoragePath *string `json:"storagePath,omitempty"` + // Version of the model format. + ModelFormatVersion *string `json:"modelFormatVersion,omitempty"` + // Name of the service account with storage secret. + ServiceAccountName *string `json:"serviceAccountName,omitempty"` +} + +// NewModelArtifactUpdate instantiates a new ModelArtifactUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelArtifactUpdate() *ModelArtifactUpdate { + this := ModelArtifactUpdate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// NewModelArtifactUpdateWithDefaults instantiates a new ModelArtifactUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelArtifactUpdateWithDefaults() *ModelArtifactUpdate { + this := ModelArtifactUpdate{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ModelArtifactUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ModelArtifactUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetUri returns the Uri field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetUri() string { + if o == nil || IsNil(o.Uri) { + var ret string + return ret + } + return *o.Uri +} + +// GetUriOk returns a tuple with the Uri field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetUriOk() (*string, bool) { + if o == nil || IsNil(o.Uri) { + return nil, false + } + return o.Uri, true +} + +// HasUri returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasUri() bool { + if o != nil && !IsNil(o.Uri) { + return true + } + + return false +} + +// SetUri gets a reference to the given string and assigns it to the Uri field. +func (o *ModelArtifactUpdate) SetUri(v string) { + o.Uri = &v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetState() ArtifactState { + if o == nil || IsNil(o.State) { + var ret ArtifactState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetStateOk() (*ArtifactState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ArtifactState and assigns it to the State field. +func (o *ModelArtifactUpdate) SetState(v ArtifactState) { + o.State = &v +} + +// GetModelFormatName returns the ModelFormatName field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetModelFormatName() string { + if o == nil || IsNil(o.ModelFormatName) { + var ret string + return ret + } + return *o.ModelFormatName +} + +// GetModelFormatNameOk returns a tuple with the ModelFormatName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetModelFormatNameOk() (*string, bool) { + if o == nil || IsNil(o.ModelFormatName) { + return nil, false + } + return o.ModelFormatName, true +} + +// HasModelFormatName returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasModelFormatName() bool { + if o != nil && !IsNil(o.ModelFormatName) { + return true + } + + return false +} + +// SetModelFormatName gets a reference to the given string and assigns it to the ModelFormatName field. +func (o *ModelArtifactUpdate) SetModelFormatName(v string) { + o.ModelFormatName = &v +} + +// GetRuntime returns the Runtime field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetRuntime() string { + if o == nil || IsNil(o.Runtime) { + var ret string + return ret + } + return *o.Runtime +} + +// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetRuntimeOk() (*string, bool) { + if o == nil || IsNil(o.Runtime) { + return nil, false + } + return o.Runtime, true +} + +// HasRuntime returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasRuntime() bool { + if o != nil && !IsNil(o.Runtime) { + return true + } + + return false +} + +// SetRuntime gets a reference to the given string and assigns it to the Runtime field. +func (o *ModelArtifactUpdate) SetRuntime(v string) { + o.Runtime = &v +} + +// GetStorageKey returns the StorageKey field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetStorageKey() string { + if o == nil || IsNil(o.StorageKey) { + var ret string + return ret + } + return *o.StorageKey +} + +// GetStorageKeyOk returns a tuple with the StorageKey field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetStorageKeyOk() (*string, bool) { + if o == nil || IsNil(o.StorageKey) { + return nil, false + } + return o.StorageKey, true +} + +// HasStorageKey returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasStorageKey() bool { + if o != nil && !IsNil(o.StorageKey) { + return true + } + + return false +} + +// SetStorageKey gets a reference to the given string and assigns it to the StorageKey field. +func (o *ModelArtifactUpdate) SetStorageKey(v string) { + o.StorageKey = &v +} + +// GetStoragePath returns the StoragePath field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetStoragePath() string { + if o == nil || IsNil(o.StoragePath) { + var ret string + return ret + } + return *o.StoragePath +} + +// GetStoragePathOk returns a tuple with the StoragePath field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetStoragePathOk() (*string, bool) { + if o == nil || IsNil(o.StoragePath) { + return nil, false + } + return o.StoragePath, true +} + +// HasStoragePath returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasStoragePath() bool { + if o != nil && !IsNil(o.StoragePath) { + return true + } + + return false +} + +// SetStoragePath gets a reference to the given string and assigns it to the StoragePath field. +func (o *ModelArtifactUpdate) SetStoragePath(v string) { + o.StoragePath = &v +} + +// GetModelFormatVersion returns the ModelFormatVersion field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetModelFormatVersion() string { + if o == nil || IsNil(o.ModelFormatVersion) { + var ret string + return ret + } + return *o.ModelFormatVersion +} + +// GetModelFormatVersionOk returns a tuple with the ModelFormatVersion field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetModelFormatVersionOk() (*string, bool) { + if o == nil || IsNil(o.ModelFormatVersion) { + return nil, false + } + return o.ModelFormatVersion, true +} + +// HasModelFormatVersion returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasModelFormatVersion() bool { + if o != nil && !IsNil(o.ModelFormatVersion) { + return true + } + + return false +} + +// SetModelFormatVersion gets a reference to the given string and assigns it to the ModelFormatVersion field. +func (o *ModelArtifactUpdate) SetModelFormatVersion(v string) { + o.ModelFormatVersion = &v +} + +// GetServiceAccountName returns the ServiceAccountName field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetServiceAccountName() string { + if o == nil || IsNil(o.ServiceAccountName) { + var ret string + return ret + } + return *o.ServiceAccountName +} + +// GetServiceAccountNameOk returns a tuple with the ServiceAccountName field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetServiceAccountNameOk() (*string, bool) { + if o == nil || IsNil(o.ServiceAccountName) { + return nil, false + } + return o.ServiceAccountName, true +} + +// HasServiceAccountName returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasServiceAccountName() bool { + if o != nil && !IsNil(o.ServiceAccountName) { + return true + } + + return false +} + +// SetServiceAccountName gets a reference to the given string and assigns it to the ServiceAccountName field. +func (o *ModelArtifactUpdate) SetServiceAccountName(v string) { + o.ServiceAccountName = &v +} + +func (o ModelArtifactUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelArtifactUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Uri) { + toSerialize["uri"] = o.Uri + } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + if !IsNil(o.ModelFormatName) { + toSerialize["modelFormatName"] = o.ModelFormatName + } + if !IsNil(o.Runtime) { + toSerialize["runtime"] = o.Runtime + } + if !IsNil(o.StorageKey) { + toSerialize["storageKey"] = o.StorageKey + } + if !IsNil(o.StoragePath) { + toSerialize["storagePath"] = o.StoragePath + } + if !IsNil(o.ModelFormatVersion) { + toSerialize["modelFormatVersion"] = o.ModelFormatVersion + } + if !IsNil(o.ServiceAccountName) { + toSerialize["serviceAccountName"] = o.ServiceAccountName + } + return toSerialize, nil +} + +type NullableModelArtifactUpdate struct { + value *ModelArtifactUpdate + isSet bool +} + +func (v NullableModelArtifactUpdate) Get() *ModelArtifactUpdate { + return v.value +} + +func (v *NullableModelArtifactUpdate) Set(val *ModelArtifactUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableModelArtifactUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableModelArtifactUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelArtifactUpdate(val *ModelArtifactUpdate) *NullableModelArtifactUpdate { + return &NullableModelArtifactUpdate{value: val, isSet: true} +} + +func (v NullableModelArtifactUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelArtifactUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_version.go b/internal/model/openapi/model_model_version.go new file mode 100644 index 00000000..87604daf --- /dev/null +++ b/internal/model/openapi/model_model_version.go @@ -0,0 +1,310 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelVersion type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelVersion{} + +// ModelVersion Represents a ModelVersion belonging to a RegisteredModel. +type ModelVersion struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` +} + +// NewModelVersion instantiates a new ModelVersion object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelVersion() *ModelVersion { + this := ModelVersion{} + return &this +} + +// NewModelVersionWithDefaults instantiates a new ModelVersion object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelVersionWithDefaults() *ModelVersion { + this := ModelVersion{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ModelVersion) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ModelVersion) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ModelVersion) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ModelVersion) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ModelVersion) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ModelVersion) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ModelVersion) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ModelVersion) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ModelVersion) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ModelVersion) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ModelVersion) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ModelVersion) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ModelVersion) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ModelVersion) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *ModelVersion) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ModelVersion) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ModelVersion) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *ModelVersion) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +func (o ModelVersion) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelVersion) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + return toSerialize, nil +} + +type NullableModelVersion struct { + value *ModelVersion + isSet bool +} + +func (v NullableModelVersion) Get() *ModelVersion { + return v.value +} + +func (v *NullableModelVersion) Set(val *ModelVersion) { + v.value = val + v.isSet = true +} + +func (v NullableModelVersion) IsSet() bool { + return v.isSet +} + +func (v *NullableModelVersion) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelVersion(val *ModelVersion) *NullableModelVersion { + return &NullableModelVersion{value: val, isSet: true} +} + +func (v NullableModelVersion) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelVersion) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_version_create.go b/internal/model/openapi/model_model_version_create.go new file mode 100644 index 00000000..c47d9a29 --- /dev/null +++ b/internal/model/openapi/model_model_version_create.go @@ -0,0 +1,226 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelVersionCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelVersionCreate{} + +// ModelVersionCreate Represents a ModelVersion belonging to a RegisteredModel. +type ModelVersionCreate struct { + // ID of the `RegisteredModel` to which this version belongs. + RegisteredModelID string `json:"registeredModelID"` + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` +} + +// NewModelVersionCreate instantiates a new ModelVersionCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelVersionCreate(registeredModelID string) *ModelVersionCreate { + this := ModelVersionCreate{} + return &this +} + +// NewModelVersionCreateWithDefaults instantiates a new ModelVersionCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelVersionCreateWithDefaults() *ModelVersionCreate { + this := ModelVersionCreate{} + return &this +} + +// GetRegisteredModelID returns the RegisteredModelID field value +func (o *ModelVersionCreate) GetRegisteredModelID() string { + if o == nil { + var ret string + return ret + } + + return o.RegisteredModelID +} + +// GetRegisteredModelIDOk returns a tuple with the RegisteredModelID field value +// and a boolean to check if the value has been set. +func (o *ModelVersionCreate) GetRegisteredModelIDOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.RegisteredModelID, true +} + +// SetRegisteredModelID sets field value +func (o *ModelVersionCreate) SetRegisteredModelID(v string) { + o.RegisteredModelID = v +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ModelVersionCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ModelVersionCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ModelVersionCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ModelVersionCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ModelVersionCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ModelVersionCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ModelVersionCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ModelVersionCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ModelVersionCreate) SetName(v string) { + o.Name = &v +} + +func (o ModelVersionCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelVersionCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["registeredModelID"] = o.RegisteredModelID + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableModelVersionCreate struct { + value *ModelVersionCreate + isSet bool +} + +func (v NullableModelVersionCreate) Get() *ModelVersionCreate { + return v.value +} + +func (v *NullableModelVersionCreate) Set(val *ModelVersionCreate) { + v.value = val + v.isSet = true +} + +func (v NullableModelVersionCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableModelVersionCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelVersionCreate(val *ModelVersionCreate) *NullableModelVersionCreate { + return &NullableModelVersionCreate{value: val, isSet: true} +} + +func (v NullableModelVersionCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelVersionCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_version_list.go b/internal/model/openapi/model_model_version_list.go new file mode 100644 index 00000000..3a0a8d03 --- /dev/null +++ b/internal/model/openapi/model_model_version_list.go @@ -0,0 +1,209 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelVersionList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelVersionList{} + +// ModelVersionList List of ModelVersion entities. +type ModelVersionList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` + // Array of `ModelVersion` entities. + Items []ModelVersion `json:"items,omitempty"` +} + +// NewModelVersionList instantiates a new ModelVersionList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelVersionList(nextPageToken string, pageSize int32, size int32) *ModelVersionList { + this := ModelVersionList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewModelVersionListWithDefaults instantiates a new ModelVersionList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelVersionListWithDefaults() *ModelVersionList { + this := ModelVersionList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *ModelVersionList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *ModelVersionList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *ModelVersionList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *ModelVersionList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *ModelVersionList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *ModelVersionList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *ModelVersionList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *ModelVersionList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *ModelVersionList) SetSize(v int32) { + o.Size = v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *ModelVersionList) GetItems() []ModelVersion { + if o == nil || IsNil(o.Items) { + var ret []ModelVersion + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionList) GetItemsOk() ([]ModelVersion, bool) { + if o == nil || IsNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *ModelVersionList) HasItems() bool { + if o != nil && !IsNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []ModelVersion and assigns it to the Items field. +func (o *ModelVersionList) SetItems(v []ModelVersion) { + o.Items = v +} + +func (o ModelVersionList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelVersionList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + if !IsNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableModelVersionList struct { + value *ModelVersionList + isSet bool +} + +func (v NullableModelVersionList) Get() *ModelVersionList { + return v.value +} + +func (v *NullableModelVersionList) Set(val *ModelVersionList) { + v.value = val + v.isSet = true +} + +func (v NullableModelVersionList) IsSet() bool { + return v.isSet +} + +func (v *NullableModelVersionList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelVersionList(val *ModelVersionList) *NullableModelVersionList { + return &NullableModelVersionList{value: val, isSet: true} +} + +func (v NullableModelVersionList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelVersionList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_model_version_update.go b/internal/model/openapi/model_model_version_update.go new file mode 100644 index 00000000..d9d5417a --- /dev/null +++ b/internal/model/openapi/model_model_version_update.go @@ -0,0 +1,162 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ModelVersionUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ModelVersionUpdate{} + +// ModelVersionUpdate Represents a ModelVersion belonging to a RegisteredModel. +type ModelVersionUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` +} + +// NewModelVersionUpdate instantiates a new ModelVersionUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewModelVersionUpdate() *ModelVersionUpdate { + this := ModelVersionUpdate{} + return &this +} + +// NewModelVersionUpdateWithDefaults instantiates a new ModelVersionUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewModelVersionUpdateWithDefaults() *ModelVersionUpdate { + this := ModelVersionUpdate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ModelVersionUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ModelVersionUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ModelVersionUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ModelVersionUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ModelVersionUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ModelVersionUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +func (o ModelVersionUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ModelVersionUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + return toSerialize, nil +} + +type NullableModelVersionUpdate struct { + value *ModelVersionUpdate + isSet bool +} + +func (v NullableModelVersionUpdate) Get() *ModelVersionUpdate { + return v.value +} + +func (v *NullableModelVersionUpdate) Set(val *ModelVersionUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableModelVersionUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableModelVersionUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelVersionUpdate(val *ModelVersionUpdate) *NullableModelVersionUpdate { + return &NullableModelVersionUpdate{value: val, isSet: true} +} + +func (v NullableModelVersionUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelVersionUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_order_by_field.go b/internal/model/openapi/model_order_by_field.go new file mode 100644 index 00000000..6c8c9e56 --- /dev/null +++ b/internal/model/openapi/model_order_by_field.go @@ -0,0 +1,112 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// OrderByField Supported fields for ordering result entities. +type OrderByField string + +// List of OrderByField +const ( + ORDERBYFIELD_CREATE_TIME OrderByField = "CREATE_TIME" + ORDERBYFIELD_LAST_UPDATE_TIME OrderByField = "LAST_UPDATE_TIME" + ORDERBYFIELD_ID OrderByField = "ID" +) + +// All allowed values of OrderByField enum +var AllowedOrderByFieldEnumValues = []OrderByField{ + "CREATE_TIME", + "LAST_UPDATE_TIME", + "ID", +} + +func (v *OrderByField) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := OrderByField(value) + for _, existing := range AllowedOrderByFieldEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid OrderByField", value) +} + +// NewOrderByFieldFromValue returns a pointer to a valid OrderByField +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewOrderByFieldFromValue(v string) (*OrderByField, error) { + ev := OrderByField(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for OrderByField: valid values are %v", v, AllowedOrderByFieldEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v OrderByField) IsValid() bool { + for _, existing := range AllowedOrderByFieldEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to OrderByField value +func (v OrderByField) Ptr() *OrderByField { + return &v +} + +type NullableOrderByField struct { + value *OrderByField + isSet bool +} + +func (v NullableOrderByField) Get() *OrderByField { + return v.value +} + +func (v *NullableOrderByField) Set(val *OrderByField) { + v.value = val + v.isSet = true +} + +func (v NullableOrderByField) IsSet() bool { + return v.isSet +} + +func (v *NullableOrderByField) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableOrderByField(val *OrderByField) *NullableOrderByField { + return &NullableOrderByField{value: val, isSet: true} +} + +func (v NullableOrderByField) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableOrderByField) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_registered_model.go b/internal/model/openapi/model_registered_model.go new file mode 100644 index 00000000..93a726f5 --- /dev/null +++ b/internal/model/openapi/model_registered_model.go @@ -0,0 +1,310 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the RegisteredModel type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RegisteredModel{} + +// RegisteredModel A registered model in model registry. A registered model has ModelVersion children. +type RegisteredModel struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` +} + +// NewRegisteredModel instantiates a new RegisteredModel object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRegisteredModel() *RegisteredModel { + this := RegisteredModel{} + return &this +} + +// NewRegisteredModelWithDefaults instantiates a new RegisteredModel object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRegisteredModelWithDefaults() *RegisteredModel { + this := RegisteredModel{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *RegisteredModel) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *RegisteredModel) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *RegisteredModel) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *RegisteredModel) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *RegisteredModel) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *RegisteredModel) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *RegisteredModel) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *RegisteredModel) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *RegisteredModel) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *RegisteredModel) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *RegisteredModel) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *RegisteredModel) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *RegisteredModel) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *RegisteredModel) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *RegisteredModel) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *RegisteredModel) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *RegisteredModel) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *RegisteredModel) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +func (o RegisteredModel) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RegisteredModel) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + return toSerialize, nil +} + +type NullableRegisteredModel struct { + value *RegisteredModel + isSet bool +} + +func (v NullableRegisteredModel) Get() *RegisteredModel { + return v.value +} + +func (v *NullableRegisteredModel) Set(val *RegisteredModel) { + v.value = val + v.isSet = true +} + +func (v NullableRegisteredModel) IsSet() bool { + return v.isSet +} + +func (v *NullableRegisteredModel) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRegisteredModel(val *RegisteredModel) *NullableRegisteredModel { + return &NullableRegisteredModel{value: val, isSet: true} +} + +func (v NullableRegisteredModel) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRegisteredModel) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_registered_model_create.go b/internal/model/openapi/model_registered_model_create.go new file mode 100644 index 00000000..507cdd9f --- /dev/null +++ b/internal/model/openapi/model_registered_model_create.go @@ -0,0 +1,199 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the RegisteredModelCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RegisteredModelCreate{} + +// RegisteredModelCreate A registered model in model registry. A registered model has ModelVersion children. +type RegisteredModelCreate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` +} + +// NewRegisteredModelCreate instantiates a new RegisteredModelCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRegisteredModelCreate() *RegisteredModelCreate { + this := RegisteredModelCreate{} + return &this +} + +// NewRegisteredModelCreateWithDefaults instantiates a new RegisteredModelCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRegisteredModelCreateWithDefaults() *RegisteredModelCreate { + this := RegisteredModelCreate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *RegisteredModelCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *RegisteredModelCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *RegisteredModelCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *RegisteredModelCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *RegisteredModelCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *RegisteredModelCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *RegisteredModelCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *RegisteredModelCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *RegisteredModelCreate) SetName(v string) { + o.Name = &v +} + +func (o RegisteredModelCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RegisteredModelCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableRegisteredModelCreate struct { + value *RegisteredModelCreate + isSet bool +} + +func (v NullableRegisteredModelCreate) Get() *RegisteredModelCreate { + return v.value +} + +func (v *NullableRegisteredModelCreate) Set(val *RegisteredModelCreate) { + v.value = val + v.isSet = true +} + +func (v NullableRegisteredModelCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableRegisteredModelCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRegisteredModelCreate(val *RegisteredModelCreate) *NullableRegisteredModelCreate { + return &NullableRegisteredModelCreate{value: val, isSet: true} +} + +func (v NullableRegisteredModelCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRegisteredModelCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_registered_model_list.go b/internal/model/openapi/model_registered_model_list.go new file mode 100644 index 00000000..05892f0a --- /dev/null +++ b/internal/model/openapi/model_registered_model_list.go @@ -0,0 +1,209 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the RegisteredModelList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RegisteredModelList{} + +// RegisteredModelList List of RegisteredModels. +type RegisteredModelList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` + // + Items []RegisteredModel `json:"items,omitempty"` +} + +// NewRegisteredModelList instantiates a new RegisteredModelList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRegisteredModelList(nextPageToken string, pageSize int32, size int32) *RegisteredModelList { + this := RegisteredModelList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewRegisteredModelListWithDefaults instantiates a new RegisteredModelList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRegisteredModelListWithDefaults() *RegisteredModelList { + this := RegisteredModelList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *RegisteredModelList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *RegisteredModelList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *RegisteredModelList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *RegisteredModelList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *RegisteredModelList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *RegisteredModelList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *RegisteredModelList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *RegisteredModelList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *RegisteredModelList) SetSize(v int32) { + o.Size = v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *RegisteredModelList) GetItems() []RegisteredModel { + if o == nil || IsNil(o.Items) { + var ret []RegisteredModel + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelList) GetItemsOk() ([]RegisteredModel, bool) { + if o == nil || IsNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *RegisteredModelList) HasItems() bool { + if o != nil && !IsNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []RegisteredModel and assigns it to the Items field. +func (o *RegisteredModelList) SetItems(v []RegisteredModel) { + o.Items = v +} + +func (o RegisteredModelList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RegisteredModelList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + if !IsNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableRegisteredModelList struct { + value *RegisteredModelList + isSet bool +} + +func (v NullableRegisteredModelList) Get() *RegisteredModelList { + return v.value +} + +func (v *NullableRegisteredModelList) Set(val *RegisteredModelList) { + v.value = val + v.isSet = true +} + +func (v NullableRegisteredModelList) IsSet() bool { + return v.isSet +} + +func (v *NullableRegisteredModelList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRegisteredModelList(val *RegisteredModelList) *NullableRegisteredModelList { + return &NullableRegisteredModelList{value: val, isSet: true} +} + +func (v NullableRegisteredModelList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRegisteredModelList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_registered_model_update.go b/internal/model/openapi/model_registered_model_update.go new file mode 100644 index 00000000..bf0817f3 --- /dev/null +++ b/internal/model/openapi/model_registered_model_update.go @@ -0,0 +1,162 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the RegisteredModelUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &RegisteredModelUpdate{} + +// RegisteredModelUpdate A registered model in model registry. A registered model has ModelVersion children. +type RegisteredModelUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` +} + +// NewRegisteredModelUpdate instantiates a new RegisteredModelUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewRegisteredModelUpdate() *RegisteredModelUpdate { + this := RegisteredModelUpdate{} + return &this +} + +// NewRegisteredModelUpdateWithDefaults instantiates a new RegisteredModelUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewRegisteredModelUpdateWithDefaults() *RegisteredModelUpdate { + this := RegisteredModelUpdate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *RegisteredModelUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *RegisteredModelUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *RegisteredModelUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *RegisteredModelUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *RegisteredModelUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *RegisteredModelUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +func (o RegisteredModelUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o RegisteredModelUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + return toSerialize, nil +} + +type NullableRegisteredModelUpdate struct { + value *RegisteredModelUpdate + isSet bool +} + +func (v NullableRegisteredModelUpdate) Get() *RegisteredModelUpdate { + return v.value +} + +func (v *NullableRegisteredModelUpdate) Set(val *RegisteredModelUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableRegisteredModelUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableRegisteredModelUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRegisteredModelUpdate(val *RegisteredModelUpdate) *NullableRegisteredModelUpdate { + return &NullableRegisteredModelUpdate{value: val, isSet: true} +} + +func (v NullableRegisteredModelUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRegisteredModelUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serve_model.go b/internal/model/openapi/model_serve_model.go new file mode 100644 index 00000000..49e2ebf9 --- /dev/null +++ b/internal/model/openapi/model_serve_model.go @@ -0,0 +1,378 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServeModel type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServeModel{} + +// ServeModel An ML model serving action. +type ServeModel struct { + LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` + // ID of the `ModelVersion` that was served in `InferenceService`. + ModelVersionId string `json:"modelVersionId"` +} + +// NewServeModel instantiates a new ServeModel object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServeModel(modelVersionId string) *ServeModel { + this := ServeModel{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + this.ModelVersionId = modelVersionId + return &this +} + +// NewServeModelWithDefaults instantiates a new ServeModel object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServeModelWithDefaults() *ServeModel { + this := ServeModel{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// GetLastKnownState returns the LastKnownState field value if set, zero value otherwise. +func (o *ServeModel) GetLastKnownState() ExecutionState { + if o == nil || IsNil(o.LastKnownState) { + var ret ExecutionState + return ret + } + return *o.LastKnownState +} + +// GetLastKnownStateOk returns a tuple with the LastKnownState field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetLastKnownStateOk() (*ExecutionState, bool) { + if o == nil || IsNil(o.LastKnownState) { + return nil, false + } + return o.LastKnownState, true +} + +// HasLastKnownState returns a boolean if a field has been set. +func (o *ServeModel) HasLastKnownState() bool { + if o != nil && !IsNil(o.LastKnownState) { + return true + } + + return false +} + +// SetLastKnownState gets a reference to the given ExecutionState and assigns it to the LastKnownState field. +func (o *ServeModel) SetLastKnownState(v ExecutionState) { + o.LastKnownState = &v +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ServeModel) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ServeModel) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ServeModel) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ServeModel) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ServeModel) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ServeModel) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ServeModel) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ServeModel) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ServeModel) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ServeModel) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ServeModel) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ServeModel) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ServeModel) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ServeModel) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *ServeModel) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ServeModel) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ServeModel) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *ServeModel) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +// GetModelVersionId returns the ModelVersionId field value +func (o *ServeModel) GetModelVersionId() string { + if o == nil { + var ret string + return ret + } + + return o.ModelVersionId +} + +// GetModelVersionIdOk returns a tuple with the ModelVersionId field value +// and a boolean to check if the value has been set. +func (o *ServeModel) GetModelVersionIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ModelVersionId, true +} + +// SetModelVersionId sets field value +func (o *ServeModel) SetModelVersionId(v string) { + o.ModelVersionId = v +} + +func (o ServeModel) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServeModel) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.LastKnownState) { + toSerialize["lastKnownState"] = o.LastKnownState + } + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + toSerialize["modelVersionId"] = o.ModelVersionId + return toSerialize, nil +} + +type NullableServeModel struct { + value *ServeModel + isSet bool +} + +func (v NullableServeModel) Get() *ServeModel { + return v.value +} + +func (v *NullableServeModel) Set(val *ServeModel) { + v.value = val + v.isSet = true +} + +func (v NullableServeModel) IsSet() bool { + return v.isSet +} + +func (v *NullableServeModel) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServeModel(val *ServeModel) *NullableServeModel { + return &NullableServeModel{value: val, isSet: true} +} + +func (v NullableServeModel) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServeModel) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serve_model_create.go b/internal/model/openapi/model_serve_model_create.go new file mode 100644 index 00000000..fc7e3c9c --- /dev/null +++ b/internal/model/openapi/model_serve_model_create.go @@ -0,0 +1,267 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServeModelCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServeModelCreate{} + +// ServeModelCreate An ML model serving action. +type ServeModelCreate struct { + LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // ID of the `ModelVersion` that was served in `InferenceService`. + ModelVersionId string `json:"modelVersionId"` +} + +// NewServeModelCreate instantiates a new ServeModelCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServeModelCreate(modelVersionId string) *ServeModelCreate { + this := ServeModelCreate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + this.ModelVersionId = modelVersionId + return &this +} + +// NewServeModelCreateWithDefaults instantiates a new ServeModelCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServeModelCreateWithDefaults() *ServeModelCreate { + this := ServeModelCreate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// GetLastKnownState returns the LastKnownState field value if set, zero value otherwise. +func (o *ServeModelCreate) GetLastKnownState() ExecutionState { + if o == nil || IsNil(o.LastKnownState) { + var ret ExecutionState + return ret + } + return *o.LastKnownState +} + +// GetLastKnownStateOk returns a tuple with the LastKnownState field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelCreate) GetLastKnownStateOk() (*ExecutionState, bool) { + if o == nil || IsNil(o.LastKnownState) { + return nil, false + } + return o.LastKnownState, true +} + +// HasLastKnownState returns a boolean if a field has been set. +func (o *ServeModelCreate) HasLastKnownState() bool { + if o != nil && !IsNil(o.LastKnownState) { + return true + } + + return false +} + +// SetLastKnownState gets a reference to the given ExecutionState and assigns it to the LastKnownState field. +func (o *ServeModelCreate) SetLastKnownState(v ExecutionState) { + o.LastKnownState = &v +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ServeModelCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ServeModelCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ServeModelCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ServeModelCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ServeModelCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ServeModelCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ServeModelCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ServeModelCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ServeModelCreate) SetName(v string) { + o.Name = &v +} + +// GetModelVersionId returns the ModelVersionId field value +func (o *ServeModelCreate) GetModelVersionId() string { + if o == nil { + var ret string + return ret + } + + return o.ModelVersionId +} + +// GetModelVersionIdOk returns a tuple with the ModelVersionId field value +// and a boolean to check if the value has been set. +func (o *ServeModelCreate) GetModelVersionIdOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ModelVersionId, true +} + +// SetModelVersionId sets field value +func (o *ServeModelCreate) SetModelVersionId(v string) { + o.ModelVersionId = v +} + +func (o ServeModelCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServeModelCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.LastKnownState) { + toSerialize["lastKnownState"] = o.LastKnownState + } + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + toSerialize["modelVersionId"] = o.ModelVersionId + return toSerialize, nil +} + +type NullableServeModelCreate struct { + value *ServeModelCreate + isSet bool +} + +func (v NullableServeModelCreate) Get() *ServeModelCreate { + return v.value +} + +func (v *NullableServeModelCreate) Set(val *ServeModelCreate) { + v.value = val + v.isSet = true +} + +func (v NullableServeModelCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableServeModelCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServeModelCreate(val *ServeModelCreate) *NullableServeModelCreate { + return &NullableServeModelCreate{value: val, isSet: true} +} + +func (v NullableServeModelCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServeModelCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serve_model_list.go b/internal/model/openapi/model_serve_model_list.go new file mode 100644 index 00000000..2b3285b6 --- /dev/null +++ b/internal/model/openapi/model_serve_model_list.go @@ -0,0 +1,209 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServeModelList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServeModelList{} + +// ServeModelList List of ServeModel entities. +type ServeModelList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` + // Array of `ModelArtifact` entities. + Items []ServeModel `json:"items,omitempty"` +} + +// NewServeModelList instantiates a new ServeModelList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServeModelList(nextPageToken string, pageSize int32, size int32) *ServeModelList { + this := ServeModelList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewServeModelListWithDefaults instantiates a new ServeModelList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServeModelListWithDefaults() *ServeModelList { + this := ServeModelList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *ServeModelList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *ServeModelList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *ServeModelList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *ServeModelList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *ServeModelList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *ServeModelList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *ServeModelList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *ServeModelList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *ServeModelList) SetSize(v int32) { + o.Size = v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *ServeModelList) GetItems() []ServeModel { + if o == nil || IsNil(o.Items) { + var ret []ServeModel + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelList) GetItemsOk() ([]ServeModel, bool) { + if o == nil || IsNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *ServeModelList) HasItems() bool { + if o != nil && !IsNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []ServeModel and assigns it to the Items field. +func (o *ServeModelList) SetItems(v []ServeModel) { + o.Items = v +} + +func (o ServeModelList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServeModelList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + if !IsNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableServeModelList struct { + value *ServeModelList + isSet bool +} + +func (v NullableServeModelList) Get() *ServeModelList { + return v.value +} + +func (v *NullableServeModelList) Set(val *ServeModelList) { + v.value = val + v.isSet = true +} + +func (v NullableServeModelList) IsSet() bool { + return v.isSet +} + +func (v *NullableServeModelList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServeModelList(val *ServeModelList) *NullableServeModelList { + return &NullableServeModelList{value: val, isSet: true} +} + +func (v NullableServeModelList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServeModelList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serve_model_update.go b/internal/model/openapi/model_serve_model_update.go new file mode 100644 index 00000000..3152ae3c --- /dev/null +++ b/internal/model/openapi/model_serve_model_update.go @@ -0,0 +1,202 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServeModelUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServeModelUpdate{} + +// ServeModelUpdate An ML model serving action. +type ServeModelUpdate struct { + LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` +} + +// NewServeModelUpdate instantiates a new ServeModelUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServeModelUpdate() *ServeModelUpdate { + this := ServeModelUpdate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// NewServeModelUpdateWithDefaults instantiates a new ServeModelUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServeModelUpdateWithDefaults() *ServeModelUpdate { + this := ServeModelUpdate{} + var lastKnownState ExecutionState = EXECUTIONSTATE_UNKNOWN + this.LastKnownState = &lastKnownState + return &this +} + +// GetLastKnownState returns the LastKnownState field value if set, zero value otherwise. +func (o *ServeModelUpdate) GetLastKnownState() ExecutionState { + if o == nil || IsNil(o.LastKnownState) { + var ret ExecutionState + return ret + } + return *o.LastKnownState +} + +// GetLastKnownStateOk returns a tuple with the LastKnownState field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelUpdate) GetLastKnownStateOk() (*ExecutionState, bool) { + if o == nil || IsNil(o.LastKnownState) { + return nil, false + } + return o.LastKnownState, true +} + +// HasLastKnownState returns a boolean if a field has been set. +func (o *ServeModelUpdate) HasLastKnownState() bool { + if o != nil && !IsNil(o.LastKnownState) { + return true + } + + return false +} + +// SetLastKnownState gets a reference to the given ExecutionState and assigns it to the LastKnownState field. +func (o *ServeModelUpdate) SetLastKnownState(v ExecutionState) { + o.LastKnownState = &v +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ServeModelUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ServeModelUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ServeModelUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ServeModelUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ServeModelUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ServeModelUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +func (o ServeModelUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServeModelUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.LastKnownState) { + toSerialize["lastKnownState"] = o.LastKnownState + } + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + return toSerialize, nil +} + +type NullableServeModelUpdate struct { + value *ServeModelUpdate + isSet bool +} + +func (v NullableServeModelUpdate) Get() *ServeModelUpdate { + return v.value +} + +func (v *NullableServeModelUpdate) Set(val *ServeModelUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableServeModelUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableServeModelUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServeModelUpdate(val *ServeModelUpdate) *NullableServeModelUpdate { + return &NullableServeModelUpdate{value: val, isSet: true} +} + +func (v NullableServeModelUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServeModelUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serving_environment.go b/internal/model/openapi/model_serving_environment.go new file mode 100644 index 00000000..d842345d --- /dev/null +++ b/internal/model/openapi/model_serving_environment.go @@ -0,0 +1,310 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServingEnvironment type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServingEnvironment{} + +// ServingEnvironment A Model Serving environment for serving `RegisteredModels`. +type ServingEnvironment struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` +} + +// NewServingEnvironment instantiates a new ServingEnvironment object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServingEnvironment() *ServingEnvironment { + this := ServingEnvironment{} + return &this +} + +// NewServingEnvironmentWithDefaults instantiates a new ServingEnvironment object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServingEnvironmentWithDefaults() *ServingEnvironment { + this := ServingEnvironment{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ServingEnvironment) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironment) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ServingEnvironment) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ServingEnvironment) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ServingEnvironment) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironment) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ServingEnvironment) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ServingEnvironment) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ServingEnvironment) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironment) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ServingEnvironment) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ServingEnvironment) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *ServingEnvironment) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironment) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *ServingEnvironment) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *ServingEnvironment) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ServingEnvironment) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironment) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ServingEnvironment) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *ServingEnvironment) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *ServingEnvironment) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironment) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *ServingEnvironment) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *ServingEnvironment) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +func (o ServingEnvironment) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServingEnvironment) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + return toSerialize, nil +} + +type NullableServingEnvironment struct { + value *ServingEnvironment + isSet bool +} + +func (v NullableServingEnvironment) Get() *ServingEnvironment { + return v.value +} + +func (v *NullableServingEnvironment) Set(val *ServingEnvironment) { + v.value = val + v.isSet = true +} + +func (v NullableServingEnvironment) IsSet() bool { + return v.isSet +} + +func (v *NullableServingEnvironment) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServingEnvironment(val *ServingEnvironment) *NullableServingEnvironment { + return &NullableServingEnvironment{value: val, isSet: true} +} + +func (v NullableServingEnvironment) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServingEnvironment) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serving_environment_create.go b/internal/model/openapi/model_serving_environment_create.go new file mode 100644 index 00000000..dbd3d5fd --- /dev/null +++ b/internal/model/openapi/model_serving_environment_create.go @@ -0,0 +1,199 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServingEnvironmentCreate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServingEnvironmentCreate{} + +// ServingEnvironmentCreate A Model Serving environment for serving `RegisteredModels`. +type ServingEnvironmentCreate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` +} + +// NewServingEnvironmentCreate instantiates a new ServingEnvironmentCreate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServingEnvironmentCreate() *ServingEnvironmentCreate { + this := ServingEnvironmentCreate{} + return &this +} + +// NewServingEnvironmentCreateWithDefaults instantiates a new ServingEnvironmentCreate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServingEnvironmentCreateWithDefaults() *ServingEnvironmentCreate { + this := ServingEnvironmentCreate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ServingEnvironmentCreate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentCreate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ServingEnvironmentCreate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ServingEnvironmentCreate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ServingEnvironmentCreate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentCreate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ServingEnvironmentCreate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ServingEnvironmentCreate) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *ServingEnvironmentCreate) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentCreate) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *ServingEnvironmentCreate) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *ServingEnvironmentCreate) SetName(v string) { + o.Name = &v +} + +func (o ServingEnvironmentCreate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServingEnvironmentCreate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + return toSerialize, nil +} + +type NullableServingEnvironmentCreate struct { + value *ServingEnvironmentCreate + isSet bool +} + +func (v NullableServingEnvironmentCreate) Get() *ServingEnvironmentCreate { + return v.value +} + +func (v *NullableServingEnvironmentCreate) Set(val *ServingEnvironmentCreate) { + v.value = val + v.isSet = true +} + +func (v NullableServingEnvironmentCreate) IsSet() bool { + return v.isSet +} + +func (v *NullableServingEnvironmentCreate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServingEnvironmentCreate(val *ServingEnvironmentCreate) *NullableServingEnvironmentCreate { + return &NullableServingEnvironmentCreate{value: val, isSet: true} +} + +func (v NullableServingEnvironmentCreate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServingEnvironmentCreate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serving_environment_list.go b/internal/model/openapi/model_serving_environment_list.go new file mode 100644 index 00000000..51c1c44b --- /dev/null +++ b/internal/model/openapi/model_serving_environment_list.go @@ -0,0 +1,209 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServingEnvironmentList type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServingEnvironmentList{} + +// ServingEnvironmentList List of ServingEnvironments. +type ServingEnvironmentList struct { + // Token to use to retrieve next page of results. + NextPageToken string `json:"nextPageToken"` + // Maximum number of resources to return in the result. + PageSize int32 `json:"pageSize"` + // Number of items in result list. + Size int32 `json:"size"` + // + Items []ServingEnvironment `json:"items,omitempty"` +} + +// NewServingEnvironmentList instantiates a new ServingEnvironmentList object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServingEnvironmentList(nextPageToken string, pageSize int32, size int32) *ServingEnvironmentList { + this := ServingEnvironmentList{} + this.NextPageToken = nextPageToken + this.PageSize = pageSize + this.Size = size + return &this +} + +// NewServingEnvironmentListWithDefaults instantiates a new ServingEnvironmentList object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServingEnvironmentListWithDefaults() *ServingEnvironmentList { + this := ServingEnvironmentList{} + return &this +} + +// GetNextPageToken returns the NextPageToken field value +func (o *ServingEnvironmentList) GetNextPageToken() string { + if o == nil { + var ret string + return ret + } + + return o.NextPageToken +} + +// GetNextPageTokenOk returns a tuple with the NextPageToken field value +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentList) GetNextPageTokenOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.NextPageToken, true +} + +// SetNextPageToken sets field value +func (o *ServingEnvironmentList) SetNextPageToken(v string) { + o.NextPageToken = v +} + +// GetPageSize returns the PageSize field value +func (o *ServingEnvironmentList) GetPageSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.PageSize +} + +// GetPageSizeOk returns a tuple with the PageSize field value +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentList) GetPageSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.PageSize, true +} + +// SetPageSize sets field value +func (o *ServingEnvironmentList) SetPageSize(v int32) { + o.PageSize = v +} + +// GetSize returns the Size field value +func (o *ServingEnvironmentList) GetSize() int32 { + if o == nil { + var ret int32 + return ret + } + + return o.Size +} + +// GetSizeOk returns a tuple with the Size field value +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentList) GetSizeOk() (*int32, bool) { + if o == nil { + return nil, false + } + return &o.Size, true +} + +// SetSize sets field value +func (o *ServingEnvironmentList) SetSize(v int32) { + o.Size = v +} + +// GetItems returns the Items field value if set, zero value otherwise. +func (o *ServingEnvironmentList) GetItems() []ServingEnvironment { + if o == nil || IsNil(o.Items) { + var ret []ServingEnvironment + return ret + } + return o.Items +} + +// GetItemsOk returns a tuple with the Items field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentList) GetItemsOk() ([]ServingEnvironment, bool) { + if o == nil || IsNil(o.Items) { + return nil, false + } + return o.Items, true +} + +// HasItems returns a boolean if a field has been set. +func (o *ServingEnvironmentList) HasItems() bool { + if o != nil && !IsNil(o.Items) { + return true + } + + return false +} + +// SetItems gets a reference to the given []ServingEnvironment and assigns it to the Items field. +func (o *ServingEnvironmentList) SetItems(v []ServingEnvironment) { + o.Items = v +} + +func (o ServingEnvironmentList) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServingEnvironmentList) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + toSerialize["nextPageToken"] = o.NextPageToken + toSerialize["pageSize"] = o.PageSize + toSerialize["size"] = o.Size + if !IsNil(o.Items) { + toSerialize["items"] = o.Items + } + return toSerialize, nil +} + +type NullableServingEnvironmentList struct { + value *ServingEnvironmentList + isSet bool +} + +func (v NullableServingEnvironmentList) Get() *ServingEnvironmentList { + return v.value +} + +func (v *NullableServingEnvironmentList) Set(val *ServingEnvironmentList) { + v.value = val + v.isSet = true +} + +func (v NullableServingEnvironmentList) IsSet() bool { + return v.isSet +} + +func (v *NullableServingEnvironmentList) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServingEnvironmentList(val *ServingEnvironmentList) *NullableServingEnvironmentList { + return &NullableServingEnvironmentList{value: val, isSet: true} +} + +func (v NullableServingEnvironmentList) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServingEnvironmentList) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_serving_environment_update.go b/internal/model/openapi/model_serving_environment_update.go new file mode 100644 index 00000000..4e7a52ba --- /dev/null +++ b/internal/model/openapi/model_serving_environment_update.go @@ -0,0 +1,162 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the ServingEnvironmentUpdate type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &ServingEnvironmentUpdate{} + +// ServingEnvironmentUpdate A Model Serving environment for serving `RegisteredModels`. +type ServingEnvironmentUpdate struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` +} + +// NewServingEnvironmentUpdate instantiates a new ServingEnvironmentUpdate object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewServingEnvironmentUpdate() *ServingEnvironmentUpdate { + this := ServingEnvironmentUpdate{} + return &this +} + +// NewServingEnvironmentUpdateWithDefaults instantiates a new ServingEnvironmentUpdate object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewServingEnvironmentUpdateWithDefaults() *ServingEnvironmentUpdate { + this := ServingEnvironmentUpdate{} + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *ServingEnvironmentUpdate) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentUpdate) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *ServingEnvironmentUpdate) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *ServingEnvironmentUpdate) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *ServingEnvironmentUpdate) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentUpdate) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *ServingEnvironmentUpdate) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *ServingEnvironmentUpdate) SetExternalID(v string) { + o.ExternalID = &v +} + +func (o ServingEnvironmentUpdate) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o ServingEnvironmentUpdate) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + return toSerialize, nil +} + +type NullableServingEnvironmentUpdate struct { + value *ServingEnvironmentUpdate + isSet bool +} + +func (v NullableServingEnvironmentUpdate) Get() *ServingEnvironmentUpdate { + return v.value +} + +func (v *NullableServingEnvironmentUpdate) Set(val *ServingEnvironmentUpdate) { + v.value = val + v.isSet = true +} + +func (v NullableServingEnvironmentUpdate) IsSet() bool { + return v.isSet +} + +func (v *NullableServingEnvironmentUpdate) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableServingEnvironmentUpdate(val *ServingEnvironmentUpdate) *NullableServingEnvironmentUpdate { + return &NullableServingEnvironmentUpdate{value: val, isSet: true} +} + +func (v NullableServingEnvironmentUpdate) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableServingEnvironmentUpdate) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/model_sort_order.go b/internal/model/openapi/model_sort_order.go new file mode 100644 index 00000000..f2cdd0e3 --- /dev/null +++ b/internal/model/openapi/model_sort_order.go @@ -0,0 +1,110 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// SortOrder Supported sort direction for ordering result entities. +type SortOrder string + +// List of SortOrder +const ( + SORTORDER_ASC SortOrder = "ASC" + SORTORDER_DESC SortOrder = "DESC" +) + +// All allowed values of SortOrder enum +var AllowedSortOrderEnumValues = []SortOrder{ + "ASC", + "DESC", +} + +func (v *SortOrder) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := SortOrder(value) + for _, existing := range AllowedSortOrderEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid SortOrder", value) +} + +// NewSortOrderFromValue returns a pointer to a valid SortOrder +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewSortOrderFromValue(v string) (*SortOrder, error) { + ev := SortOrder(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for SortOrder: valid values are %v", v, AllowedSortOrderEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v SortOrder) IsValid() bool { + for _, existing := range AllowedSortOrderEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to SortOrder value +func (v SortOrder) Ptr() *SortOrder { + return &v +} + +type NullableSortOrder struct { + value *SortOrder + isSet bool +} + +func (v NullableSortOrder) Get() *SortOrder { + return v.value +} + +func (v *NullableSortOrder) Set(val *SortOrder) { + v.value = val + v.isSet = true +} + +func (v NullableSortOrder) IsSet() bool { + return v.isSet +} + +func (v *NullableSortOrder) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableSortOrder(val *SortOrder) *NullableSortOrder { + return &NullableSortOrder{value: val, isSet: true} +} + +func (v NullableSortOrder) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableSortOrder) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/internal/model/openapi/response.go b/internal/model/openapi/response.go new file mode 100644 index 00000000..7156934b --- /dev/null +++ b/internal/model/openapi/response.go @@ -0,0 +1,47 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "net/http" +) + +// APIResponse stores the API response returned by the server. +type APIResponse struct { + *http.Response `json:"-"` + Message string `json:"message,omitempty"` + // Operation is the name of the OpenAPI operation. + Operation string `json:"operation,omitempty"` + // RequestURL is the request URL. This value is always available, even if the + // embedded *http.Response is nil. + RequestURL string `json:"url,omitempty"` + // Method is the HTTP method used for the request. This value is always + // available, even if the embedded *http.Response is nil. + Method string `json:"method,omitempty"` + // Payload holds the contents of the response body (which may be nil or empty). + // This is provided here as the raw response.Body() reader will have already + // been drained. + Payload []byte `json:"-"` +} + +// NewAPIResponse returns a new APIResponse object. +func NewAPIResponse(r *http.Response) *APIResponse { + + response := &APIResponse{Response: r} + return response +} + +// NewAPIResponseWithError returns a new APIResponse object with the provided error message. +func NewAPIResponseWithError(errorMessage string) *APIResponse { + + response := &APIResponse{Message: errorMessage} + return response +} diff --git a/internal/model/openapi/utils.go b/internal/model/openapi/utils.go new file mode 100644 index 00000000..98fec2c7 --- /dev/null +++ b/internal/model/openapi/utils.go @@ -0,0 +1,347 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "reflect" + "time" +) + +// PtrBool is a helper routine that returns a pointer to given boolean value. +func PtrBool(v bool) *bool { return &v } + +// PtrInt is a helper routine that returns a pointer to given integer value. +func PtrInt(v int) *int { return &v } + +// PtrInt32 is a helper routine that returns a pointer to given integer value. +func PtrInt32(v int32) *int32 { return &v } + +// PtrInt64 is a helper routine that returns a pointer to given integer value. +func PtrInt64(v int64) *int64 { return &v } + +// PtrFloat32 is a helper routine that returns a pointer to given float value. +func PtrFloat32(v float32) *float32 { return &v } + +// PtrFloat64 is a helper routine that returns a pointer to given float value. +func PtrFloat64(v float64) *float64 { return &v } + +// PtrString is a helper routine that returns a pointer to given string value. +func PtrString(v string) *string { return &v } + +// PtrTime is helper routine that returns a pointer to given Time value. +func PtrTime(v time.Time) *time.Time { return &v } + +type NullableBool struct { + value *bool + isSet bool +} + +func (v NullableBool) Get() *bool { + return v.value +} + +func (v *NullableBool) Set(val *bool) { + v.value = val + v.isSet = true +} + +func (v NullableBool) IsSet() bool { + return v.isSet +} + +func (v *NullableBool) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableBool(val *bool) *NullableBool { + return &NullableBool{value: val, isSet: true} +} + +func (v NullableBool) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableBool) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt struct { + value *int + isSet bool +} + +func (v NullableInt) Get() *int { + return v.value +} + +func (v *NullableInt) Set(val *int) { + v.value = val + v.isSet = true +} + +func (v NullableInt) IsSet() bool { + return v.isSet +} + +func (v *NullableInt) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt(val *int) *NullableInt { + return &NullableInt{value: val, isSet: true} +} + +func (v NullableInt) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt32 struct { + value *int32 + isSet bool +} + +func (v NullableInt32) Get() *int32 { + return v.value +} + +func (v *NullableInt32) Set(val *int32) { + v.value = val + v.isSet = true +} + +func (v NullableInt32) IsSet() bool { + return v.isSet +} + +func (v *NullableInt32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt32(val *int32) *NullableInt32 { + return &NullableInt32{value: val, isSet: true} +} + +func (v NullableInt32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableInt64 struct { + value *int64 + isSet bool +} + +func (v NullableInt64) Get() *int64 { + return v.value +} + +func (v *NullableInt64) Set(val *int64) { + v.value = val + v.isSet = true +} + +func (v NullableInt64) IsSet() bool { + return v.isSet +} + +func (v *NullableInt64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInt64(val *int64) *NullableInt64 { + return &NullableInt64{value: val, isSet: true} +} + +func (v NullableInt64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInt64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat32 struct { + value *float32 + isSet bool +} + +func (v NullableFloat32) Get() *float32 { + return v.value +} + +func (v *NullableFloat32) Set(val *float32) { + v.value = val + v.isSet = true +} + +func (v NullableFloat32) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat32) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat32(val *float32) *NullableFloat32 { + return &NullableFloat32{value: val, isSet: true} +} + +func (v NullableFloat32) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat32) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableFloat64 struct { + value *float64 + isSet bool +} + +func (v NullableFloat64) Get() *float64 { + return v.value +} + +func (v *NullableFloat64) Set(val *float64) { + v.value = val + v.isSet = true +} + +func (v NullableFloat64) IsSet() bool { + return v.isSet +} + +func (v *NullableFloat64) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableFloat64(val *float64) *NullableFloat64 { + return &NullableFloat64{value: val, isSet: true} +} + +func (v NullableFloat64) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableFloat64) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableString struct { + value *string + isSet bool +} + +func (v NullableString) Get() *string { + return v.value +} + +func (v *NullableString) Set(val *string) { + v.value = val + v.isSet = true +} + +func (v NullableString) IsSet() bool { + return v.isSet +} + +func (v *NullableString) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableString(val *string) *NullableString { + return &NullableString{value: val, isSet: true} +} + +func (v NullableString) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableString) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +type NullableTime struct { + value *time.Time + isSet bool +} + +func (v NullableTime) Get() *time.Time { + return v.value +} + +func (v *NullableTime) Set(val *time.Time) { + v.value = val + v.isSet = true +} + +func (v NullableTime) IsSet() bool { + return v.isSet +} + +func (v *NullableTime) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableTime(val *time.Time) *NullableTime { + return &NullableTime{value: val, isSet: true} +} + +func (v NullableTime) MarshalJSON() ([]byte, error) { + return v.value.MarshalJSON() +} + +func (v *NullableTime) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} + +// IsNil checks if an input is nil +func IsNil(i interface{}) bool { + if i == nil { + return true + } + switch reflect.TypeOf(i).Kind() { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: + return reflect.ValueOf(i).IsNil() + case reflect.Array: + return reflect.ValueOf(i).IsZero() + } + return false +} + +type MappedNullable interface { + ToMap() (map[string]interface{}, error) +} diff --git a/internal/server/openapi/.openapi-generator/FILES b/internal/server/openapi/.openapi-generator/FILES new file mode 100644 index 00000000..b42c7f76 --- /dev/null +++ b/internal/server/openapi/.openapi-generator/FILES @@ -0,0 +1,55 @@ +api.go +api_model_registry_service.go +error.go +helpers.go +impl.go +logger.go +model_artifact.go +model_artifact_list.go +model_artifact_state.go +model_base_artifact.go +model_base_artifact_create.go +model_base_artifact_update.go +model_base_execution.go +model_base_execution_create.go +model_base_execution_update.go +model_base_resource.go +model_base_resource_create.go +model_base_resource_list.go +model_base_resource_update.go +model_error.go +model_execution_state.go +model_inference_service.go +model_inference_service_create.go +model_inference_service_list.go +model_inference_service_update.go +model_metadata_value.go +model_metadata_value_one_of.go +model_metadata_value_one_of_1.go +model_metadata_value_one_of_2.go +model_metadata_value_one_of_3.go +model_metadata_value_one_of_4.go +model_metadata_value_one_of_5.go +model_model_artifact.go +model_model_artifact_create.go +model_model_artifact_list.go +model_model_artifact_update.go +model_model_version.go +model_model_version_create.go +model_model_version_list.go +model_model_version_update.go +model_order_by_field.go +model_registered_model.go +model_registered_model_create.go +model_registered_model_list.go +model_registered_model_update.go +model_serve_model.go +model_serve_model_create.go +model_serve_model_list.go +model_serve_model_update.go +model_serving_environment.go +model_serving_environment_create.go +model_serving_environment_list.go +model_serving_environment_update.go +model_sort_order.go +routers.go diff --git a/internal/server/openapi/.openapi-generator/VERSION b/internal/server/openapi/.openapi-generator/VERSION new file mode 100644 index 00000000..73a86b19 --- /dev/null +++ b/internal/server/openapi/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.0.1 \ No newline at end of file diff --git a/internal/server/openapi/api.go b/internal/server/openapi/api.go new file mode 100644 index 00000000..51c7ad32 --- /dev/null +++ b/internal/server/openapi/api.go @@ -0,0 +1,99 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + model "github.com/opendatahub-io/model-registry/internal/model/openapi" + "net/http" +) + +// ModelRegistryServiceAPIRouter defines the required methods for binding the api requests to a responses for the ModelRegistryServiceAPI +// The ModelRegistryServiceAPIRouter implementation should parse necessary information from the http request, +// pass the data to a ModelRegistryServiceAPIServicer to perform the required actions, then write the service results to the http response. +type ModelRegistryServiceAPIRouter interface { + CreateEnvironmentInferenceService(http.ResponseWriter, *http.Request) + CreateInferenceService(http.ResponseWriter, *http.Request) + CreateInferenceServiceServe(http.ResponseWriter, *http.Request) + CreateModelArtifact(http.ResponseWriter, *http.Request) + CreateModelVersion(http.ResponseWriter, *http.Request) + CreateModelVersionArtifact(http.ResponseWriter, *http.Request) + CreateRegisteredModel(http.ResponseWriter, *http.Request) + CreateRegisteredModelVersion(http.ResponseWriter, *http.Request) + CreateServingEnvironment(http.ResponseWriter, *http.Request) + FindInferenceService(http.ResponseWriter, *http.Request) + FindModelArtifact(http.ResponseWriter, *http.Request) + FindModelVersion(http.ResponseWriter, *http.Request) + FindRegisteredModel(http.ResponseWriter, *http.Request) + FindServingEnvironment(http.ResponseWriter, *http.Request) + GetEnvironmentInferenceServices(http.ResponseWriter, *http.Request) + GetInferenceService(http.ResponseWriter, *http.Request) + GetInferenceServiceModel(http.ResponseWriter, *http.Request) + GetInferenceServiceServes(http.ResponseWriter, *http.Request) + GetInferenceServiceVersion(http.ResponseWriter, *http.Request) + GetInferenceServices(http.ResponseWriter, *http.Request) + GetModelArtifact(http.ResponseWriter, *http.Request) + GetModelArtifacts(http.ResponseWriter, *http.Request) + GetModelVersion(http.ResponseWriter, *http.Request) + GetModelVersionArtifacts(http.ResponseWriter, *http.Request) + GetModelVersions(http.ResponseWriter, *http.Request) + GetRegisteredModel(http.ResponseWriter, *http.Request) + GetRegisteredModelVersions(http.ResponseWriter, *http.Request) + GetRegisteredModels(http.ResponseWriter, *http.Request) + GetServingEnvironment(http.ResponseWriter, *http.Request) + GetServingEnvironments(http.ResponseWriter, *http.Request) + UpdateInferenceService(http.ResponseWriter, *http.Request) + UpdateModelArtifact(http.ResponseWriter, *http.Request) + UpdateModelVersion(http.ResponseWriter, *http.Request) + UpdateRegisteredModel(http.ResponseWriter, *http.Request) + UpdateServingEnvironment(http.ResponseWriter, *http.Request) +} + +// ModelRegistryServiceAPIServicer defines the api actions for the ModelRegistryServiceAPI service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can be ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type ModelRegistryServiceAPIServicer interface { + CreateEnvironmentInferenceService(context.Context, string, model.InferenceServiceCreate) (ImplResponse, error) + CreateInferenceService(context.Context, model.InferenceServiceCreate) (ImplResponse, error) + CreateInferenceServiceServe(context.Context, string, model.ServeModelCreate) (ImplResponse, error) + CreateModelArtifact(context.Context, model.ModelArtifactCreate) (ImplResponse, error) + CreateModelVersion(context.Context, model.ModelVersionCreate) (ImplResponse, error) + CreateModelVersionArtifact(context.Context, string, model.Artifact) (ImplResponse, error) + CreateRegisteredModel(context.Context, model.RegisteredModelCreate) (ImplResponse, error) + CreateRegisteredModelVersion(context.Context, string, model.ModelVersion) (ImplResponse, error) + CreateServingEnvironment(context.Context, model.ServingEnvironmentCreate) (ImplResponse, error) + FindInferenceService(context.Context, string, string) (ImplResponse, error) + FindModelArtifact(context.Context, string, string) (ImplResponse, error) + FindModelVersion(context.Context, string, string) (ImplResponse, error) + FindRegisteredModel(context.Context, string, string) (ImplResponse, error) + FindServingEnvironment(context.Context, string, string) (ImplResponse, error) + GetEnvironmentInferenceServices(context.Context, string, string, string, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetInferenceService(context.Context, string) (ImplResponse, error) + GetInferenceServiceModel(context.Context, string) (ImplResponse, error) + GetInferenceServiceServes(context.Context, string, string, string, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetInferenceServiceVersion(context.Context, string) (ImplResponse, error) + GetInferenceServices(context.Context, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetModelArtifact(context.Context, string) (ImplResponse, error) + GetModelArtifacts(context.Context, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetModelVersion(context.Context, string) (ImplResponse, error) + GetModelVersionArtifacts(context.Context, string, string, string, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetModelVersions(context.Context, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetRegisteredModel(context.Context, string) (ImplResponse, error) + GetRegisteredModelVersions(context.Context, string, string, string, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetRegisteredModels(context.Context, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + GetServingEnvironment(context.Context, string) (ImplResponse, error) + GetServingEnvironments(context.Context, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) + UpdateInferenceService(context.Context, string, model.InferenceServiceUpdate) (ImplResponse, error) + UpdateModelArtifact(context.Context, string, model.ModelArtifactUpdate) (ImplResponse, error) + UpdateModelVersion(context.Context, string, model.ModelVersion) (ImplResponse, error) + UpdateRegisteredModel(context.Context, string, model.RegisteredModelUpdate) (ImplResponse, error) + UpdateServingEnvironment(context.Context, string, model.ServingEnvironmentUpdate) (ImplResponse, error) +} diff --git a/internal/server/openapi/api_model_registry_service.go b/internal/server/openapi/api_model_registry_service.go new file mode 100644 index 00000000..1e223952 --- /dev/null +++ b/internal/server/openapi/api_model_registry_service.go @@ -0,0 +1,948 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "net/http" + "strings" + + "github.com/go-chi/chi/v5" + model "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +// ModelRegistryServiceAPIController binds http requests to an api service and writes the service results to the http response +type ModelRegistryServiceAPIController struct { + service ModelRegistryServiceAPIServicer + errorHandler ErrorHandler +} + +// ModelRegistryServiceAPIOption for how the controller is set up. +type ModelRegistryServiceAPIOption func(*ModelRegistryServiceAPIController) + +// WithModelRegistryServiceAPIErrorHandler inject ErrorHandler into controller +func WithModelRegistryServiceAPIErrorHandler(h ErrorHandler) ModelRegistryServiceAPIOption { + return func(c *ModelRegistryServiceAPIController) { + c.errorHandler = h + } +} + +// NewModelRegistryServiceAPIController creates a default api controller +func NewModelRegistryServiceAPIController(s ModelRegistryServiceAPIServicer, opts ...ModelRegistryServiceAPIOption) Router { + controller := &ModelRegistryServiceAPIController{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the ModelRegistryServiceAPIController +func (c *ModelRegistryServiceAPIController) Routes() Routes { + return Routes{ + "CreateEnvironmentInferenceService": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}/inference_services", + c.CreateEnvironmentInferenceService, + }, + "CreateInferenceService": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/inference_services", + c.CreateInferenceService, + }, + "CreateInferenceServiceServe": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/serves", + c.CreateInferenceServiceServe, + }, + "CreateModelArtifact": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/model_artifacts", + c.CreateModelArtifact, + }, + "CreateModelVersion": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/model_versions", + c.CreateModelVersion, + }, + "CreateModelVersionArtifact": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts", + c.CreateModelVersionArtifact, + }, + "CreateRegisteredModel": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/registered_models", + c.CreateRegisteredModel, + }, + "CreateRegisteredModelVersion": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}/versions", + c.CreateRegisteredModelVersion, + }, + "CreateServingEnvironment": Route{ + strings.ToUpper("Post"), + "/api/model_registry/v1alpha1/serving_environments", + c.CreateServingEnvironment, + }, + "FindInferenceService": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/inference_service", + c.FindInferenceService, + }, + "FindModelArtifact": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/model_artifact", + c.FindModelArtifact, + }, + "FindModelVersion": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/model_version", + c.FindModelVersion, + }, + "FindRegisteredModel": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/registered_model", + c.FindRegisteredModel, + }, + "FindServingEnvironment": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/serving_environment", + c.FindServingEnvironment, + }, + "GetEnvironmentInferenceServices": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}/inference_services", + c.GetEnvironmentInferenceServices, + }, + "GetInferenceService": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}", + c.GetInferenceService, + }, + "GetInferenceServiceModel": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/model", + c.GetInferenceServiceModel, + }, + "GetInferenceServiceServes": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/serves", + c.GetInferenceServiceServes, + }, + "GetInferenceServiceVersion": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/version", + c.GetInferenceServiceVersion, + }, + "GetInferenceServices": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/inference_services", + c.GetInferenceServices, + }, + "GetModelArtifact": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/model_artifacts/{modelartifactId}", + c.GetModelArtifact, + }, + "GetModelArtifacts": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/model_artifacts", + c.GetModelArtifacts, + }, + "GetModelVersion": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/model_versions/{modelversionId}", + c.GetModelVersion, + }, + "GetModelVersionArtifacts": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts", + c.GetModelVersionArtifacts, + }, + "GetModelVersions": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/model_versions", + c.GetModelVersions, + }, + "GetRegisteredModel": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}", + c.GetRegisteredModel, + }, + "GetRegisteredModelVersions": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}/versions", + c.GetRegisteredModelVersions, + }, + "GetRegisteredModels": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/registered_models", + c.GetRegisteredModels, + }, + "GetServingEnvironment": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}", + c.GetServingEnvironment, + }, + "GetServingEnvironments": Route{ + strings.ToUpper("Get"), + "/api/model_registry/v1alpha1/serving_environments", + c.GetServingEnvironments, + }, + "UpdateInferenceService": Route{ + strings.ToUpper("Patch"), + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}", + c.UpdateInferenceService, + }, + "UpdateModelArtifact": Route{ + strings.ToUpper("Patch"), + "/api/model_registry/v1alpha1/model_artifacts/{modelartifactId}", + c.UpdateModelArtifact, + }, + "UpdateModelVersion": Route{ + strings.ToUpper("Patch"), + "/api/model_registry/v1alpha1/model_versions/{modelversionId}", + c.UpdateModelVersion, + }, + "UpdateRegisteredModel": Route{ + strings.ToUpper("Patch"), + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}", + c.UpdateRegisteredModel, + }, + "UpdateServingEnvironment": Route{ + strings.ToUpper("Patch"), + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}", + c.UpdateServingEnvironment, + }, + } +} + +// CreateEnvironmentInferenceService - Create a InferenceService in ServingEnvironment +func (c *ModelRegistryServiceAPIController) CreateEnvironmentInferenceService(w http.ResponseWriter, r *http.Request) { + servingenvironmentIdParam := chi.URLParam(r, "servingenvironmentId") + inferenceServiceCreateParam := model.InferenceServiceCreate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&inferenceServiceCreateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertInferenceServiceCreateRequired(inferenceServiceCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertInferenceServiceCreateConstraints(inferenceServiceCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateEnvironmentInferenceService(r.Context(), servingenvironmentIdParam, inferenceServiceCreateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateInferenceService - Create a InferenceService +func (c *ModelRegistryServiceAPIController) CreateInferenceService(w http.ResponseWriter, r *http.Request) { + inferenceServiceCreateParam := model.InferenceServiceCreate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&inferenceServiceCreateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertInferenceServiceCreateRequired(inferenceServiceCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertInferenceServiceCreateConstraints(inferenceServiceCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateInferenceService(r.Context(), inferenceServiceCreateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateInferenceServiceServe - Create a ServeModel action in a InferenceService +func (c *ModelRegistryServiceAPIController) CreateInferenceServiceServe(w http.ResponseWriter, r *http.Request) { + inferenceserviceIdParam := chi.URLParam(r, "inferenceserviceId") + serveModelCreateParam := model.ServeModelCreate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&serveModelCreateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertServeModelCreateRequired(serveModelCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertServeModelCreateConstraints(serveModelCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateInferenceServiceServe(r.Context(), inferenceserviceIdParam, serveModelCreateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateModelArtifact - Create a ModelArtifact +func (c *ModelRegistryServiceAPIController) CreateModelArtifact(w http.ResponseWriter, r *http.Request) { + modelArtifactCreateParam := model.ModelArtifactCreate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&modelArtifactCreateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertModelArtifactCreateRequired(modelArtifactCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertModelArtifactCreateConstraints(modelArtifactCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateModelArtifact(r.Context(), modelArtifactCreateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateModelVersion - Create a ModelVersion +func (c *ModelRegistryServiceAPIController) CreateModelVersion(w http.ResponseWriter, r *http.Request) { + modelVersionCreateParam := model.ModelVersionCreate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&modelVersionCreateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertModelVersionCreateRequired(modelVersionCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertModelVersionCreateConstraints(modelVersionCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateModelVersion(r.Context(), modelVersionCreateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateModelVersionArtifact - Create an Artifact in a ModelVersion +func (c *ModelRegistryServiceAPIController) CreateModelVersionArtifact(w http.ResponseWriter, r *http.Request) { + modelversionIdParam := chi.URLParam(r, "modelversionId") + artifactParam := model.Artifact{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&artifactParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertArtifactRequired(artifactParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertArtifactConstraints(artifactParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateModelVersionArtifact(r.Context(), modelversionIdParam, artifactParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateRegisteredModel - Create a RegisteredModel +func (c *ModelRegistryServiceAPIController) CreateRegisteredModel(w http.ResponseWriter, r *http.Request) { + registeredModelCreateParam := model.RegisteredModelCreate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(®isteredModelCreateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertRegisteredModelCreateRequired(registeredModelCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertRegisteredModelCreateConstraints(registeredModelCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateRegisteredModel(r.Context(), registeredModelCreateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateRegisteredModelVersion - Create a ModelVersion in RegisteredModel +func (c *ModelRegistryServiceAPIController) CreateRegisteredModelVersion(w http.ResponseWriter, r *http.Request) { + registeredmodelIdParam := chi.URLParam(r, "registeredmodelId") + modelVersionParam := model.ModelVersion{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&modelVersionParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertModelVersionRequired(modelVersionParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertModelVersionConstraints(modelVersionParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateRegisteredModelVersion(r.Context(), registeredmodelIdParam, modelVersionParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// CreateServingEnvironment - Create a ServingEnvironment +func (c *ModelRegistryServiceAPIController) CreateServingEnvironment(w http.ResponseWriter, r *http.Request) { + servingEnvironmentCreateParam := model.ServingEnvironmentCreate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&servingEnvironmentCreateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertServingEnvironmentCreateRequired(servingEnvironmentCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertServingEnvironmentCreateConstraints(servingEnvironmentCreateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.CreateServingEnvironment(r.Context(), servingEnvironmentCreateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// FindInferenceService - Get an InferenceServices that matches search parameters. +func (c *ModelRegistryServiceAPIController) FindInferenceService(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + result, err := c.service.FindInferenceService(r.Context(), nameParam, externalIDParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// FindModelArtifact - Get a ModelArtifact that matches search parameters. +func (c *ModelRegistryServiceAPIController) FindModelArtifact(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + result, err := c.service.FindModelArtifact(r.Context(), nameParam, externalIDParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// FindModelVersion - Get a ModelVersion that matches search parameters. +func (c *ModelRegistryServiceAPIController) FindModelVersion(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + result, err := c.service.FindModelVersion(r.Context(), nameParam, externalIDParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// FindRegisteredModel - Get a RegisteredModel that matches search parameters. +func (c *ModelRegistryServiceAPIController) FindRegisteredModel(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + result, err := c.service.FindRegisteredModel(r.Context(), nameParam, externalIDParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// FindServingEnvironment - Find ServingEnvironment +func (c *ModelRegistryServiceAPIController) FindServingEnvironment(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + result, err := c.service.FindServingEnvironment(r.Context(), nameParam, externalIDParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetEnvironmentInferenceServices - List All ServingEnvironment's InferenceServices +func (c *ModelRegistryServiceAPIController) GetEnvironmentInferenceServices(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + servingenvironmentIdParam := chi.URLParam(r, "servingenvironmentId") + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetEnvironmentInferenceServices(r.Context(), servingenvironmentIdParam, nameParam, externalIDParam, pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetInferenceService - Get a InferenceService +func (c *ModelRegistryServiceAPIController) GetInferenceService(w http.ResponseWriter, r *http.Request) { + inferenceserviceIdParam := chi.URLParam(r, "inferenceserviceId") + result, err := c.service.GetInferenceService(r.Context(), inferenceserviceIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetInferenceServiceModel - Get InferenceService's RegisteredModel +func (c *ModelRegistryServiceAPIController) GetInferenceServiceModel(w http.ResponseWriter, r *http.Request) { + inferenceserviceIdParam := chi.URLParam(r, "inferenceserviceId") + result, err := c.service.GetInferenceServiceModel(r.Context(), inferenceserviceIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetInferenceServiceServes - List All InferenceService's ServeModel actions +func (c *ModelRegistryServiceAPIController) GetInferenceServiceServes(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + inferenceserviceIdParam := chi.URLParam(r, "inferenceserviceId") + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetInferenceServiceServes(r.Context(), inferenceserviceIdParam, nameParam, externalIDParam, pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetInferenceServiceVersion - Get InferenceService's ModelVersion +func (c *ModelRegistryServiceAPIController) GetInferenceServiceVersion(w http.ResponseWriter, r *http.Request) { + inferenceserviceIdParam := chi.URLParam(r, "inferenceserviceId") + result, err := c.service.GetInferenceServiceVersion(r.Context(), inferenceserviceIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetInferenceServices - List All InferenceServices +func (c *ModelRegistryServiceAPIController) GetInferenceServices(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetInferenceServices(r.Context(), pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetModelArtifact - Get a ModelArtifact +func (c *ModelRegistryServiceAPIController) GetModelArtifact(w http.ResponseWriter, r *http.Request) { + modelartifactIdParam := chi.URLParam(r, "modelartifactId") + result, err := c.service.GetModelArtifact(r.Context(), modelartifactIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetModelArtifacts - List All ModelArtifacts +func (c *ModelRegistryServiceAPIController) GetModelArtifacts(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetModelArtifacts(r.Context(), pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetModelVersion - Get a ModelVersion +func (c *ModelRegistryServiceAPIController) GetModelVersion(w http.ResponseWriter, r *http.Request) { + modelversionIdParam := chi.URLParam(r, "modelversionId") + result, err := c.service.GetModelVersion(r.Context(), modelversionIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetModelVersionArtifacts - List All ModelVersion's artifacts +func (c *ModelRegistryServiceAPIController) GetModelVersionArtifacts(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + modelversionIdParam := chi.URLParam(r, "modelversionId") + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetModelVersionArtifacts(r.Context(), modelversionIdParam, nameParam, externalIDParam, pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetModelVersions - List All ModelVersions +func (c *ModelRegistryServiceAPIController) GetModelVersions(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetModelVersions(r.Context(), pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetRegisteredModel - Get a RegisteredModel +func (c *ModelRegistryServiceAPIController) GetRegisteredModel(w http.ResponseWriter, r *http.Request) { + registeredmodelIdParam := chi.URLParam(r, "registeredmodelId") + result, err := c.service.GetRegisteredModel(r.Context(), registeredmodelIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetRegisteredModelVersions - List All RegisteredModel's ModelVersions +func (c *ModelRegistryServiceAPIController) GetRegisteredModelVersions(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + registeredmodelIdParam := chi.URLParam(r, "registeredmodelId") + nameParam := query.Get("name") + externalIDParam := query.Get("externalID") + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetRegisteredModelVersions(r.Context(), registeredmodelIdParam, nameParam, externalIDParam, pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetRegisteredModels - List All RegisteredModels +func (c *ModelRegistryServiceAPIController) GetRegisteredModels(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetRegisteredModels(r.Context(), pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetServingEnvironment - Get a ServingEnvironment +func (c *ModelRegistryServiceAPIController) GetServingEnvironment(w http.ResponseWriter, r *http.Request) { + servingenvironmentIdParam := chi.URLParam(r, "servingenvironmentId") + result, err := c.service.GetServingEnvironment(r.Context(), servingenvironmentIdParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// GetServingEnvironments - List All ServingEnvironments +func (c *ModelRegistryServiceAPIController) GetServingEnvironments(w http.ResponseWriter, r *http.Request) { + query := r.URL.Query() + pageSizeParam := query.Get("pageSize") + orderByParam := query.Get("orderBy") + sortOrderParam := query.Get("sortOrder") + nextPageTokenParam := query.Get("nextPageToken") + result, err := c.service.GetServingEnvironments(r.Context(), pageSizeParam, model.OrderByField(orderByParam), model.SortOrder(sortOrderParam), nextPageTokenParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// UpdateInferenceService - Update a InferenceService +func (c *ModelRegistryServiceAPIController) UpdateInferenceService(w http.ResponseWriter, r *http.Request) { + inferenceserviceIdParam := chi.URLParam(r, "inferenceserviceId") + inferenceServiceUpdateParam := model.InferenceServiceUpdate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&inferenceServiceUpdateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertInferenceServiceUpdateRequired(inferenceServiceUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertInferenceServiceUpdateConstraints(inferenceServiceUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.UpdateInferenceService(r.Context(), inferenceserviceIdParam, inferenceServiceUpdateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// UpdateModelArtifact - Update a ModelArtifact +func (c *ModelRegistryServiceAPIController) UpdateModelArtifact(w http.ResponseWriter, r *http.Request) { + modelartifactIdParam := chi.URLParam(r, "modelartifactId") + modelArtifactUpdateParam := model.ModelArtifactUpdate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&modelArtifactUpdateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertModelArtifactUpdateRequired(modelArtifactUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertModelArtifactUpdateConstraints(modelArtifactUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.UpdateModelArtifact(r.Context(), modelartifactIdParam, modelArtifactUpdateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// UpdateModelVersion - Update a ModelVersion +func (c *ModelRegistryServiceAPIController) UpdateModelVersion(w http.ResponseWriter, r *http.Request) { + modelversionIdParam := chi.URLParam(r, "modelversionId") + modelVersionParam := model.ModelVersion{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&modelVersionParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertModelVersionRequired(modelVersionParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertModelVersionConstraints(modelVersionParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.UpdateModelVersion(r.Context(), modelversionIdParam, modelVersionParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// UpdateRegisteredModel - Update a RegisteredModel +func (c *ModelRegistryServiceAPIController) UpdateRegisteredModel(w http.ResponseWriter, r *http.Request) { + registeredmodelIdParam := chi.URLParam(r, "registeredmodelId") + registeredModelUpdateParam := model.RegisteredModelUpdate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(®isteredModelUpdateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertRegisteredModelUpdateRequired(registeredModelUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertRegisteredModelUpdateConstraints(registeredModelUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.UpdateRegisteredModel(r.Context(), registeredmodelIdParam, registeredModelUpdateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} + +// UpdateServingEnvironment - Update a ServingEnvironment +func (c *ModelRegistryServiceAPIController) UpdateServingEnvironment(w http.ResponseWriter, r *http.Request) { + servingenvironmentIdParam := chi.URLParam(r, "servingenvironmentId") + servingEnvironmentUpdateParam := model.ServingEnvironmentUpdate{} + d := json.NewDecoder(r.Body) + d.DisallowUnknownFields() + if err := d.Decode(&servingEnvironmentUpdateParam); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + if err := AssertServingEnvironmentUpdateRequired(servingEnvironmentUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := AssertServingEnvironmentUpdateConstraints(servingEnvironmentUpdateParam); err != nil { + c.errorHandler(w, r, err, nil) + return + } + result, err := c.service.UpdateServingEnvironment(r.Context(), servingenvironmentIdParam, servingEnvironmentUpdateParam) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code, w) +} diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go new file mode 100644 index 00000000..e9cd5509 --- /dev/null +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -0,0 +1,764 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "context" + "errors" + model "github.com/opendatahub-io/model-registry/internal/model/openapi" + "net/http" +) + +// ModelRegistryServiceAPIService is a service that implements the logic for the ModelRegistryServiceAPIServicer +// This service should implement the business logic for every endpoint for the ModelRegistryServiceAPI API. +// Include any external packages or services that will be required by this service. +type ModelRegistryServiceAPIService struct { +} + +// NewModelRegistryServiceAPIService creates a default api service +func NewModelRegistryServiceAPIService() ModelRegistryServiceAPIServicer { + return &ModelRegistryServiceAPIService{} +} + +// CreateEnvironmentInferenceService - Create a InferenceService in ServingEnvironment +func (s *ModelRegistryServiceAPIService) CreateEnvironmentInferenceService(ctx context.Context, servingenvironmentId string, inferenceServiceCreate model.InferenceServiceCreate) (ImplResponse, error) { + // TODO - update CreateEnvironmentInferenceService with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(201, InferenceService{}) or use other options such as http.Ok ... + // return Response(201, InferenceService{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateEnvironmentInferenceService method not implemented") +} + +// CreateInferenceService - Create a InferenceService +func (s *ModelRegistryServiceAPIService) CreateInferenceService(ctx context.Context, inferenceServiceCreate model.InferenceServiceCreate) (ImplResponse, error) { + // TODO - update CreateInferenceService with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... + // return Response(200, InferenceService{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateInferenceService method not implemented") +} + +// CreateInferenceServiceServe - Create a ServeModel action in a InferenceService +func (s *ModelRegistryServiceAPIService) CreateInferenceServiceServe(ctx context.Context, inferenceserviceId string, serveModelCreate model.ServeModelCreate) (ImplResponse, error) { + // TODO - update CreateInferenceServiceServe with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(201, ServeModel{}) or use other options such as http.Ok ... + // return Response(201, ServeModel{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateInferenceServiceServe method not implemented") +} + +// CreateModelArtifact - Create a ModelArtifact +func (s *ModelRegistryServiceAPIService) CreateModelArtifact(ctx context.Context, modelArtifactCreate model.ModelArtifactCreate) (ImplResponse, error) { + // TODO - update CreateModelArtifact with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(201, ModelArtifact{}) or use other options such as http.Ok ... + // return Response(201, ModelArtifact{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateModelArtifact method not implemented") +} + +// CreateModelVersion - Create a ModelVersion +func (s *ModelRegistryServiceAPIService) CreateModelVersion(ctx context.Context, modelVersionCreate model.ModelVersionCreate) (ImplResponse, error) { + // TODO - update CreateModelVersion with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(201, ModelVersion{}) or use other options such as http.Ok ... + // return Response(201, ModelVersion{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateModelVersion method not implemented") +} + +// CreateModelVersionArtifact - Create an Artifact in a ModelVersion +func (s *ModelRegistryServiceAPIService) CreateModelVersionArtifact(ctx context.Context, modelversionId string, artifact model.Artifact) (ImplResponse, error) { + // TODO - update CreateModelVersionArtifact with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, Artifact{}) or use other options such as http.Ok ... + // return Response(200, Artifact{}), nil + + // TODO: Uncomment the next line to return response Response(201, Artifact{}) or use other options such as http.Ok ... + // return Response(201, Artifact{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateModelVersionArtifact method not implemented") +} + +// CreateRegisteredModel - Create a RegisteredModel +func (s *ModelRegistryServiceAPIService) CreateRegisteredModel(ctx context.Context, registeredModelCreate model.RegisteredModelCreate) (ImplResponse, error) { + // TODO - update CreateRegisteredModel with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(201, RegisteredModel{}) or use other options such as http.Ok ... + // return Response(201, RegisteredModel{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateRegisteredModel method not implemented") +} + +// CreateRegisteredModelVersion - Create a ModelVersion in RegisteredModel +func (s *ModelRegistryServiceAPIService) CreateRegisteredModelVersion(ctx context.Context, registeredmodelId string, modelVersion model.ModelVersion) (ImplResponse, error) { + // TODO - update CreateRegisteredModelVersion with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(201, ModelVersion{}) or use other options such as http.Ok ... + // return Response(201, ModelVersion{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateRegisteredModelVersion method not implemented") +} + +// CreateServingEnvironment - Create a ServingEnvironment +func (s *ModelRegistryServiceAPIService) CreateServingEnvironment(ctx context.Context, servingEnvironmentCreate model.ServingEnvironmentCreate) (ImplResponse, error) { + // TODO - update CreateServingEnvironment with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(201, ServingEnvironment{}) or use other options such as http.Ok ... + // return Response(201, ServingEnvironment{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("CreateServingEnvironment method not implemented") +} + +// FindInferenceService - Get an InferenceServices that matches search parameters. +func (s *ModelRegistryServiceAPIService) FindInferenceService(ctx context.Context, name string, externalID string) (ImplResponse, error) { + // TODO - update FindInferenceService with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... + // return Response(200, InferenceService{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("FindInferenceService method not implemented") +} + +// FindModelArtifact - Get a ModelArtifact that matches search parameters. +func (s *ModelRegistryServiceAPIService) FindModelArtifact(ctx context.Context, name string, externalID string) (ImplResponse, error) { + // TODO - update FindModelArtifact with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelArtifact{}) or use other options such as http.Ok ... + // return Response(200, ModelArtifact{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("FindModelArtifact method not implemented") +} + +// FindModelVersion - Get a ModelVersion that matches search parameters. +func (s *ModelRegistryServiceAPIService) FindModelVersion(ctx context.Context, name string, externalID string) (ImplResponse, error) { + // TODO - update FindModelVersion with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... + // return Response(200, ModelVersion{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("FindModelVersion method not implemented") +} + +// FindRegisteredModel - Get a RegisteredModel that matches search parameters. +func (s *ModelRegistryServiceAPIService) FindRegisteredModel(ctx context.Context, name string, externalID string) (ImplResponse, error) { + // TODO - update FindRegisteredModel with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... + // return Response(200, RegisteredModel{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("FindRegisteredModel method not implemented") +} + +// FindServingEnvironment - Find ServingEnvironment +func (s *ModelRegistryServiceAPIService) FindServingEnvironment(ctx context.Context, name string, externalID string) (ImplResponse, error) { + // TODO - update FindServingEnvironment with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ServingEnvironment{}) or use other options such as http.Ok ... + // return Response(200, ServingEnvironment{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("FindServingEnvironment method not implemented") +} + +// GetEnvironmentInferenceServices - List All ServingEnvironment's InferenceServices +func (s *ModelRegistryServiceAPIService) GetEnvironmentInferenceServices(ctx context.Context, servingenvironmentId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetEnvironmentInferenceServices with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, InferenceServiceList{}) or use other options such as http.Ok ... + // return Response(200, InferenceServiceList{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetEnvironmentInferenceServices method not implemented") +} + +// GetInferenceService - Get a InferenceService +func (s *ModelRegistryServiceAPIService) GetInferenceService(ctx context.Context, inferenceserviceId string) (ImplResponse, error) { + // TODO - update GetInferenceService with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... + // return Response(200, InferenceService{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceService method not implemented") +} + +// GetInferenceServiceModel - Get InferenceService's RegisteredModel +func (s *ModelRegistryServiceAPIService) GetInferenceServiceModel(ctx context.Context, inferenceserviceId string) (ImplResponse, error) { + // TODO - update GetInferenceServiceModel with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... + // return Response(200, RegisteredModel{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServiceModel method not implemented") +} + +// GetInferenceServiceServes - List All InferenceService's ServeModel actions +func (s *ModelRegistryServiceAPIService) GetInferenceServiceServes(ctx context.Context, inferenceserviceId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetInferenceServiceServes with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ServeModelList{}) or use other options such as http.Ok ... + // return Response(200, ServeModelList{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServiceServes method not implemented") +} + +// GetInferenceServiceVersion - Get InferenceService's ModelVersion +func (s *ModelRegistryServiceAPIService) GetInferenceServiceVersion(ctx context.Context, inferenceserviceId string) (ImplResponse, error) { + // TODO - update GetInferenceServiceVersion with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... + // return Response(200, ModelVersion{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServiceVersion method not implemented") +} + +// GetInferenceServices - List All InferenceServices +func (s *ModelRegistryServiceAPIService) GetInferenceServices(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetInferenceServices with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, InferenceServiceList{}) or use other options such as http.Ok ... + // return Response(200, InferenceServiceList{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServices method not implemented") +} + +// GetModelArtifact - Get a ModelArtifact +func (s *ModelRegistryServiceAPIService) GetModelArtifact(ctx context.Context, modelartifactId string) (ImplResponse, error) { + // TODO - update GetModelArtifact with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelArtifact{}) or use other options such as http.Ok ... + // return Response(200, ModelArtifact{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetModelArtifact method not implemented") +} + +// GetModelArtifacts - List All ModelArtifacts +func (s *ModelRegistryServiceAPIService) GetModelArtifacts(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetModelArtifacts with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelArtifactList{}) or use other options such as http.Ok ... + // return Response(200, ModelArtifactList{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetModelArtifacts method not implemented") +} + +// GetModelVersion - Get a ModelVersion +func (s *ModelRegistryServiceAPIService) GetModelVersion(ctx context.Context, modelversionId string) (ImplResponse, error) { + // TODO - update GetModelVersion with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... + // return Response(200, ModelVersion{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetModelVersion method not implemented") +} + +// GetModelVersionArtifacts - List All ModelVersion's artifacts +func (s *ModelRegistryServiceAPIService) GetModelVersionArtifacts(ctx context.Context, modelversionId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetModelVersionArtifacts with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ArtifactList{}) or use other options such as http.Ok ... + // return Response(200, ArtifactList{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetModelVersionArtifacts method not implemented") +} + +// GetModelVersions - List All ModelVersions +func (s *ModelRegistryServiceAPIService) GetModelVersions(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetModelVersions with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelVersionList{}) or use other options such as http.Ok ... + // return Response(200, ModelVersionList{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetModelVersions method not implemented") +} + +// GetRegisteredModel - Get a RegisteredModel +func (s *ModelRegistryServiceAPIService) GetRegisteredModel(ctx context.Context, registeredmodelId string) (ImplResponse, error) { + // TODO - update GetRegisteredModel with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... + // return Response(200, RegisteredModel{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetRegisteredModel method not implemented") +} + +// GetRegisteredModelVersions - List All RegisteredModel's ModelVersions +func (s *ModelRegistryServiceAPIService) GetRegisteredModelVersions(ctx context.Context, registeredmodelId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetRegisteredModelVersions with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelVersionList{}) or use other options such as http.Ok ... + // return Response(200, ModelVersionList{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetRegisteredModelVersions method not implemented") +} + +// GetRegisteredModels - List All RegisteredModels +func (s *ModelRegistryServiceAPIService) GetRegisteredModels(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetRegisteredModels with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, RegisteredModelList{}) or use other options such as http.Ok ... + // return Response(200, RegisteredModelList{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetRegisteredModels method not implemented") +} + +// GetServingEnvironment - Get a ServingEnvironment +func (s *ModelRegistryServiceAPIService) GetServingEnvironment(ctx context.Context, servingenvironmentId string) (ImplResponse, error) { + // TODO - update GetServingEnvironment with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ServingEnvironment{}) or use other options such as http.Ok ... + // return Response(200, ServingEnvironment{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetServingEnvironment method not implemented") +} + +// GetServingEnvironments - List All ServingEnvironments +func (s *ModelRegistryServiceAPIService) GetServingEnvironments(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { + // TODO - update GetServingEnvironments with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ServingEnvironmentList{}) or use other options such as http.Ok ... + // return Response(200, ServingEnvironmentList{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("GetServingEnvironments method not implemented") +} + +// UpdateInferenceService - Update a InferenceService +func (s *ModelRegistryServiceAPIService) UpdateInferenceService(ctx context.Context, inferenceserviceId string, inferenceServiceUpdate model.InferenceServiceUpdate) (ImplResponse, error) { + // TODO - update UpdateInferenceService with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... + // return Response(200, InferenceService{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("UpdateInferenceService method not implemented") +} + +// UpdateModelArtifact - Update a ModelArtifact +func (s *ModelRegistryServiceAPIService) UpdateModelArtifact(ctx context.Context, modelartifactId string, modelArtifactUpdate model.ModelArtifactUpdate) (ImplResponse, error) { + // TODO - update UpdateModelArtifact with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelArtifact{}) or use other options such as http.Ok ... + // return Response(200, ModelArtifact{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("UpdateModelArtifact method not implemented") +} + +// UpdateModelVersion - Update a ModelVersion +func (s *ModelRegistryServiceAPIService) UpdateModelVersion(ctx context.Context, modelversionId string, modelVersion model.ModelVersion) (ImplResponse, error) { + // TODO - update UpdateModelVersion with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... + // return Response(200, ModelVersion{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("UpdateModelVersion method not implemented") +} + +// UpdateRegisteredModel - Update a RegisteredModel +func (s *ModelRegistryServiceAPIService) UpdateRegisteredModel(ctx context.Context, registeredmodelId string, registeredModelUpdate model.RegisteredModelUpdate) (ImplResponse, error) { + // TODO - update UpdateRegisteredModel with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... + // return Response(200, RegisteredModel{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("UpdateRegisteredModel method not implemented") +} + +// UpdateServingEnvironment - Update a ServingEnvironment +func (s *ModelRegistryServiceAPIService) UpdateServingEnvironment(ctx context.Context, servingenvironmentId string, servingEnvironmentUpdate model.ServingEnvironmentUpdate) (ImplResponse, error) { + // TODO - update UpdateServingEnvironment with the required logic for this service method. + // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + + // TODO: Uncomment the next line to return response Response(200, ServingEnvironment{}) or use other options such as http.Ok ... + // return Response(200, ServingEnvironment{}), nil + + // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... + // return Response(400, Error{}), nil + + // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... + // return Response(401, Error{}), nil + + // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... + // return Response(404, Error{}), nil + + // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... + // return Response(500, Error{}), nil + + return Response(http.StatusNotImplemented, nil), errors.New("UpdateServingEnvironment method not implemented") +} diff --git a/internal/server/openapi/error.go b/internal/server/openapi/error.go new file mode 100644 index 00000000..670c7ca9 --- /dev/null +++ b/internal/server/openapi/error.go @@ -0,0 +1,62 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "errors" + "fmt" + "net/http" +) + +var ( + // ErrTypeAssertionError is thrown when type an interface does not match the asserted type + ErrTypeAssertionError = errors.New("unable to assert type") +) + +// ParsingError indicates that an error has occurred when parsing request parameters +type ParsingError struct { + Err error +} + +func (e *ParsingError) Unwrap() error { + return e.Err +} + +func (e *ParsingError) Error() string { + return e.Err.Error() +} + +// RequiredError indicates that an error has occurred when parsing request parameters +type RequiredError struct { + Field string +} + +func (e *RequiredError) Error() string { + return fmt.Sprintf("required field '%s' is zero value.", e.Field) +} + +// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if +// you would like errors to be handled differently from the DefaultErrorHandler +type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) + +// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing +// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used. +func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) { + if _, ok := err.(*ParsingError); ok { + // Handle parsing errors + EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), w) + } else if _, ok := err.(*RequiredError); ok { + // Handle missing required errors + EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), w) + } else { + // Handle all other errors + EncodeJSONResponse(err.Error(), &result.Code, w) + } +} diff --git a/internal/server/openapi/helpers.go b/internal/server/openapi/helpers.go new file mode 100644 index 00000000..57e2b44b --- /dev/null +++ b/internal/server/openapi/helpers.go @@ -0,0 +1,60 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "reflect" +) + +// Response return a ImplResponse struct filled +func Response(code int, body interface{}) ImplResponse { + return ImplResponse{ + Code: code, + Body: body, + } +} + +// IsZeroValue checks if the val is the zero-ed value. +func IsZeroValue(val interface{}) bool { + return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface()) +} + +// AssertRecurseInterfaceRequired recursively checks each struct in a slice against the callback. +// This method traverse nested slices in a preorder fashion. +func AssertRecurseInterfaceRequired[T any](obj interface{}, callback func(T) error) error { + return AssertRecurseValueRequired(reflect.ValueOf(obj), callback) +} + +// AssertRecurseValueRequired checks each struct in the nested slice against the callback. +// This method traverse nested slices in a preorder fashion. ErrTypeAssertionError is thrown if +// the underlying struct does not match type T. +func AssertRecurseValueRequired[T any](value reflect.Value, callback func(T) error) error { + switch value.Kind() { + // If it is a struct we check using callback + case reflect.Struct: + obj, ok := value.Interface().(T) + if !ok { + return ErrTypeAssertionError + } + + if err := callback(obj); err != nil { + return err + } + + // If it is a slice we continue recursion + case reflect.Slice: + for i := 0; i < value.Len(); i += 1 { + if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil { + return err + } + } + } + return nil +} diff --git a/internal/server/openapi/impl.go b/internal/server/openapi/impl.go new file mode 100644 index 00000000..0901dc5e --- /dev/null +++ b/internal/server/openapi/impl.go @@ -0,0 +1,16 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +// ImplResponse defines an implementation response with error code and the associated body +type ImplResponse struct { + Code int + Body interface{} +} diff --git a/internal/server/openapi/logger.go b/internal/server/openapi/logger.go new file mode 100644 index 00000000..f8eedd2d --- /dev/null +++ b/internal/server/openapi/logger.go @@ -0,0 +1,32 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "log" + "net/http" + "time" +) + +func Logger(inner http.Handler, name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + inner.ServeHTTP(w, r) + + log.Printf( + "%s %s %s %s", + r.Method, + r.RequestURI, + name, + time.Since(start), + ) + }) +} diff --git a/internal/server/openapi/routers.go b/internal/server/openapi/routers.go new file mode 100644 index 00000000..04881f7b --- /dev/null +++ b/internal/server/openapi/routers.go @@ -0,0 +1,297 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + "encoding/json" + "errors" + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + "github.com/golang/glog" + "io" + "mime/multipart" + "net/http" + "os" + "strconv" + "strings" +) + +//lint:file-ignore U1000 Ignore all unused code, it's generated + +// A Route defines the parameters for an api endpoint +type Route struct { + Method string + Pattern string + HandlerFunc http.HandlerFunc +} + +// Routes is a map of defined api endpoints +type Routes map[string]Route + +// Router defines the required methods for retrieving api routes +type Router interface { + Routes() Routes +} + +const errMsgRequiredMissing = "required parameter is missing" +const errMsgMinValueConstraint = "provided parameter is not respecting minimum value constraint" +const errMsgMaxValueConstraint = "provided parameter is not respecting maximum value constraint" + +// NewRouter creates a new router for any number of api routers +func NewRouter(routers ...Router) chi.Router { + router := chi.NewRouter() + router.Use(middleware.Logger) + for _, api := range routers { + for _, route := range api.Routes() { + handler := route.HandlerFunc + router.Method(route.Method, route.Pattern, handler) + } + } + + return router +} + +// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code +func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + if status != nil { + w.WriteHeader(*status) + } else { + w.WriteHeader(http.StatusOK) + } + + if i != nil { + if err := json.NewEncoder(w).Encode(i); err != nil { + // FIXME: is it too late to inform the client of an error at this point?? + glog.Errorf("error encoding JSON response: %v", err) + } + } +} + +// ReadFormFileToTempFile reads file data from a request form and writes it to a temporary file +func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) { + _, fileHeader, err := r.FormFile(key) + if err != nil { + return nil, err + } + + return readFileHeaderToTempFile(fileHeader) +} + +// ReadFormFilesToTempFiles reads files array data from a request form and writes it to a temporary files +func ReadFormFilesToTempFiles(r *http.Request, key string) ([]*os.File, error) { + if err := r.ParseMultipartForm(32 << 20); err != nil { + return nil, err + } + + files := make([]*os.File, 0, len(r.MultipartForm.File[key])) + + for _, fileHeader := range r.MultipartForm.File[key] { + file, err := readFileHeaderToTempFile(fileHeader) + if err != nil { + return nil, err + } + + files = append(files, file) + } + + return files, nil +} + +// readFileHeaderToTempFile reads multipart.FileHeader and writes it to a temporary file +func readFileHeaderToTempFile(fileHeader *multipart.FileHeader) (*os.File, error) { + formFile, err := fileHeader.Open() + if err != nil { + return nil, err + } + + defer formFile.Close() + + fileBytes, err := io.ReadAll(formFile) + if err != nil { + return nil, err + } + + file, err := os.CreateTemp("", fileHeader.Filename) + if err != nil { + return nil, err + } + + defer file.Close() + + // FIXME: return values are ignored!!! + _, _ = file.Write(fileBytes) + + return file, nil +} + +type Number interface { + ~int32 | ~int64 | ~float32 | ~float64 +} + +type ParseString[T Number | string | bool] func(v string) (T, error) + +// parseFloat64 parses a string parameter to an float64. +func parseFloat64(param string) (float64, error) { + if param == "" { + return 0, nil + } + + return strconv.ParseFloat(param, 64) +} + +// parseFloat32 parses a string parameter to an float32. +func parseFloat32(param string) (float32, error) { + if param == "" { + return 0, nil + } + + v, err := strconv.ParseFloat(param, 32) + return float32(v), err +} + +// parseInt64 parses a string parameter to an int64. +func parseInt64(param string) (int64, error) { + if param == "" { + return 0, nil + } + + return strconv.ParseInt(param, 10, 64) +} + +// parseInt32 parses a string parameter to an int32. +func parseInt32(param string) (int32, error) { + if param == "" { + return 0, nil + } + + val, err := strconv.ParseInt(param, 10, 32) + return int32(val), err +} + +// parseBool parses a string parameter to an bool. +func parseBool(param string) (bool, error) { + if param == "" { + return false, nil + } + + return strconv.ParseBool(param) +} + +type Operation[T Number | string | bool] func(actual string) (T, bool, error) + +func WithRequire[T Number | string | bool](parse ParseString[T]) Operation[T] { + var empty T + return func(actual string) (T, bool, error) { + if actual == "" { + return empty, false, errors.New(errMsgRequiredMissing) + } + + v, err := parse(actual) + return v, false, err + } +} + +func WithDefaultOrParse[T Number | string | bool](def T, parse ParseString[T]) Operation[T] { + return func(actual string) (T, bool, error) { + if actual == "" { + return def, true, nil + } + + v, err := parse(actual) + return v, false, err + } +} + +func WithParse[T Number | string | bool](parse ParseString[T]) Operation[T] { + return func(actual string) (T, bool, error) { + v, err := parse(actual) + return v, false, err + } +} + +type Constraint[T Number | string | bool] func(actual T) error + +func WithMinimum[T Number](expected T) Constraint[T] { + return func(actual T) error { + if actual < expected { + return errors.New(errMsgMinValueConstraint) + } + + return nil + } +} + +func WithMaximum[T Number](expected T) Constraint[T] { + return func(actual T) error { + if actual > expected { + return errors.New(errMsgMaxValueConstraint) + } + + return nil + } +} + +// parseNumericParameter parses a numeric parameter to its respective type. +func parseNumericParameter[T Number](param string, fn Operation[T], checks ...Constraint[T]) (T, error) { + v, ok, err := fn(param) + if err != nil { + return 0, err + } + + if !ok { + for _, check := range checks { + if err := check(v); err != nil { + return 0, err + } + } + } + + return v, nil +} + +// parseBoolParameter parses a string parameter to a bool +func parseBoolParameter(param string, fn Operation[bool]) (bool, error) { + v, _, err := fn(param) + return v, err +} + +// parseNumericArrayParameter parses a string parameter containing array of values to its respective type. +func parseNumericArrayParameter[T Number](param, delim string, required bool, fn Operation[T], checks ...Constraint[T]) ([]T, error) { + if param == "" { + if required { + return nil, errors.New(errMsgRequiredMissing) + } + + return nil, nil + } + + str := strings.Split(param, delim) + values := make([]T, len(str)) + + for i, s := range str { + v, ok, err := fn(s) + if err != nil { + return nil, err + } + + if !ok { + for _, check := range checks { + if err := check(v); err != nil { + return nil, err + } + } + } + + values[i] = v + } + + return values, nil +} diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go new file mode 100644 index 00000000..6b8dfc89 --- /dev/null +++ b/internal/server/openapi/type_asserts.go @@ -0,0 +1,652 @@ +/* + * Model Registry REST API + * + * REST API for Model Registry to create and manage ML model metadata + * + * API version: 1.0.0 + * Generated by: OpenAPI Generator (https://openapi-generator.tech) + */ + +package openapi + +import ( + model "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +// AssertArtifactRequired checks if the required fields are not zero-ed +func AssertArtifactRequired(obj model.Artifact) error { + elements := map[string]interface{}{ + "artifactType": obj.ModelArtifact.ArtifactType, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertArtifactConstraints checks if the values respects the defined constraints +func AssertArtifactConstraints(obj model.Artifact) error { + return nil +} + +// AssertArtifactListRequired checks if the required fields are not zero-ed +func AssertArtifactListRequired(obj model.ArtifactList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Items { + if err := AssertArtifactRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertArtifactListConstraints checks if the values respects the defined constraints +func AssertArtifactListConstraints(obj model.ArtifactList) error { + return nil +} + + +// AssertArtifactStateRequired checks if the required fields are not zero-ed +func AssertArtifactStateRequired(obj model.ArtifactState) error { + return nil +} + +// AssertArtifactStateConstraints checks if the values respects the defined constraints +func AssertArtifactStateConstraints(obj model.ArtifactState) error { + return nil +} + + +// AssertBaseArtifactCreateRequired checks if the required fields are not zero-ed +func AssertBaseArtifactCreateRequired(obj model.BaseArtifactCreate) error { + return nil +} + +// AssertBaseArtifactCreateConstraints checks if the values respects the defined constraints +func AssertBaseArtifactCreateConstraints(obj model.BaseArtifactCreate) error { + return nil +} + + +// AssertBaseArtifactRequired checks if the required fields are not zero-ed +func AssertBaseArtifactRequired(obj model.BaseArtifact) error { + elements := map[string]interface{}{ + "artifactType": obj.ArtifactType, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertBaseArtifactConstraints checks if the values respects the defined constraints +func AssertBaseArtifactConstraints(obj model.BaseArtifact) error { + return nil +} + + +// AssertBaseArtifactUpdateRequired checks if the required fields are not zero-ed +func AssertBaseArtifactUpdateRequired(obj model.BaseArtifactUpdate) error { + return nil +} + +// AssertBaseArtifactUpdateConstraints checks if the values respects the defined constraints +func AssertBaseArtifactUpdateConstraints(obj model.BaseArtifactUpdate) error { + return nil +} + + +// AssertBaseExecutionCreateRequired checks if the required fields are not zero-ed +func AssertBaseExecutionCreateRequired(obj model.BaseExecutionCreate) error { + return nil +} + +// AssertBaseExecutionCreateConstraints checks if the values respects the defined constraints +func AssertBaseExecutionCreateConstraints(obj model.BaseExecutionCreate) error { + return nil +} + + +// AssertBaseExecutionRequired checks if the required fields are not zero-ed +func AssertBaseExecutionRequired(obj model.BaseExecution) error { + return nil +} + +// AssertBaseExecutionConstraints checks if the values respects the defined constraints +func AssertBaseExecutionConstraints(obj model.BaseExecution) error { + return nil +} + + +// AssertBaseExecutionUpdateRequired checks if the required fields are not zero-ed +func AssertBaseExecutionUpdateRequired(obj model.BaseExecutionUpdate) error { + return nil +} + +// AssertBaseExecutionUpdateConstraints checks if the values respects the defined constraints +func AssertBaseExecutionUpdateConstraints(obj model.BaseExecutionUpdate) error { + return nil +} + + +// AssertBaseResourceCreateRequired checks if the required fields are not zero-ed +func AssertBaseResourceCreateRequired(obj model.BaseResourceCreate) error { + return nil +} + +// AssertBaseResourceCreateConstraints checks if the values respects the defined constraints +func AssertBaseResourceCreateConstraints(obj model.BaseResourceCreate) error { + return nil +} + + +// AssertBaseResourceRequired checks if the required fields are not zero-ed +func AssertBaseResourceRequired(obj model.BaseResource) error { + return nil +} + +// AssertBaseResourceConstraints checks if the values respects the defined constraints +func AssertBaseResourceConstraints(obj model.BaseResource) error { + return nil +} + + +// AssertBaseResourceListRequired checks if the required fields are not zero-ed +func AssertBaseResourceListRequired(obj model.BaseResourceList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertBaseResourceListConstraints checks if the values respects the defined constraints +func AssertBaseResourceListConstraints(obj model.BaseResourceList) error { + return nil +} + + +// AssertBaseResourceUpdateRequired checks if the required fields are not zero-ed +func AssertBaseResourceUpdateRequired(obj model.BaseResourceUpdate) error { + return nil +} + +// AssertBaseResourceUpdateConstraints checks if the values respects the defined constraints +func AssertBaseResourceUpdateConstraints(obj model.BaseResourceUpdate) error { + return nil +} + + +// AssertErrorRequired checks if the required fields are not zero-ed +func AssertErrorRequired(obj model.Error) error { + elements := map[string]interface{}{ + "code": obj.Code, + "message": obj.Message, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertErrorConstraints checks if the values respects the defined constraints +func AssertErrorConstraints(obj model.Error) error { + return nil +} + + +// AssertExecutionStateRequired checks if the required fields are not zero-ed +func AssertExecutionStateRequired(obj model.ExecutionState) error { + return nil +} + +// AssertExecutionStateConstraints checks if the values respects the defined constraints +func AssertExecutionStateConstraints(obj model.ExecutionState) error { + return nil +} + + +// AssertInferenceServiceCreateRequired checks if the required fields are not zero-ed +func AssertInferenceServiceCreateRequired(obj model.InferenceServiceCreate) error { + elements := map[string]interface{}{ + "registeredModelId": obj.RegisteredModelId, + "servingEnvironmentId": obj.ServingEnvironmentId, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertInferenceServiceCreateConstraints checks if the values respects the defined constraints +func AssertInferenceServiceCreateConstraints(obj model.InferenceServiceCreate) error { + return nil +} + + +// AssertInferenceServiceRequired checks if the required fields are not zero-ed +func AssertInferenceServiceRequired(obj model.InferenceService) error { + return nil +} + +// AssertInferenceServiceConstraints checks if the values respects the defined constraints +func AssertInferenceServiceConstraints(obj model.InferenceService) error { + return nil +} + + +// AssertInferenceServiceListRequired checks if the required fields are not zero-ed +func AssertInferenceServiceListRequired(obj model.InferenceServiceList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Items { + if err := AssertInferenceServiceRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertInferenceServiceListConstraints checks if the values respects the defined constraints +func AssertInferenceServiceListConstraints(obj model.InferenceServiceList) error { + return nil +} + + +// AssertInferenceServiceUpdateRequired checks if the required fields are not zero-ed +func AssertInferenceServiceUpdateRequired(obj model.InferenceServiceUpdate) error { + return nil +} + +// AssertInferenceServiceUpdateConstraints checks if the values respects the defined constraints +func AssertInferenceServiceUpdateConstraints(obj model.InferenceServiceUpdate) error { + return nil +} + + +// AssertMetadataValueRequired checks if the required fields are not zero-ed +func AssertMetadataValueRequired(obj model.MetadataValue) error { + return nil +} + +// AssertMetadataValueConstraints checks if the values respects the defined constraints +func AssertMetadataValueConstraints(obj model.MetadataValue) error { + return nil +} + + +// AssertModelArtifactCreateRequired checks if the required fields are not zero-ed +func AssertModelArtifactCreateRequired(obj model.ModelArtifactCreate) error { + return nil +} + +// AssertModelArtifactCreateConstraints checks if the values respects the defined constraints +func AssertModelArtifactCreateConstraints(obj model.ModelArtifactCreate) error { + return nil +} + + +// AssertModelArtifactRequired checks if the required fields are not zero-ed +func AssertModelArtifactRequired(obj model.ModelArtifact) error { + elements := map[string]interface{}{ + "artifactType": obj.ArtifactType, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertModelArtifactConstraints checks if the values respects the defined constraints +func AssertModelArtifactConstraints(obj model.ModelArtifact) error { + return nil +} + + +// AssertModelArtifactListRequired checks if the required fields are not zero-ed +func AssertModelArtifactListRequired(obj model.ModelArtifactList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Items { + if err := AssertModelArtifactRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertModelArtifactListConstraints checks if the values respects the defined constraints +func AssertModelArtifactListConstraints(obj model.ModelArtifactList) error { + return nil +} + +// AssertModelArtifactUpdateRequired checks if the required fields are not zero-ed +func AssertModelArtifactUpdateRequired(obj model.ModelArtifactUpdate) error { + return nil +} + +// AssertModelArtifactUpdateConstraints checks if the values respects the defined constraints +func AssertModelArtifactUpdateConstraints(obj model.ModelArtifactUpdate) error { + return nil +} + +// AssertModelVersionCreateRequired checks if the required fields are not zero-ed +func AssertModelVersionCreateRequired(obj model.ModelVersionCreate) error { + elements := map[string]interface{}{ + "registeredModelID": obj.RegisteredModelID, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertModelVersionCreateConstraints checks if the values respects the defined constraints +func AssertModelVersionCreateConstraints(obj model.ModelVersionCreate) error { + return nil +} + +// AssertModelVersionRequired checks if the required fields are not zero-ed +func AssertModelVersionRequired(obj model.ModelVersion) error { + return nil +} + +// AssertModelVersionConstraints checks if the values respects the defined constraints +func AssertModelVersionConstraints(obj model.ModelVersion) error { + return nil +} + +// AssertModelVersionListRequired checks if the required fields are not zero-ed +func AssertModelVersionListRequired(obj model.ModelVersionList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Items { + if err := AssertModelVersionRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertModelVersionListConstraints checks if the values respects the defined constraints +func AssertModelVersionListConstraints(obj model.ModelVersionList) error { + return nil +} + +// AssertModelVersionUpdateRequired checks if the required fields are not zero-ed +func AssertModelVersionUpdateRequired(obj model.ModelVersionUpdate) error { + return nil +} + +// AssertModelVersionUpdateConstraints checks if the values respects the defined constraints +func AssertModelVersionUpdateConstraints(obj model.ModelVersionUpdate) error { + return nil +} + +// AssertOrderByFieldRequired checks if the required fields are not zero-ed +func AssertOrderByFieldRequired(obj model.OrderByField) error { + return nil +} + +// AssertOrderByFieldConstraints checks if the values respects the defined constraints +func AssertOrderByFieldConstraints(obj model.OrderByField) error { + return nil +} + +// AssertRegisteredModelCreateRequired checks if the required fields are not zero-ed +func AssertRegisteredModelCreateRequired(obj model.RegisteredModelCreate) error { + return nil +} + +// AssertRegisteredModelCreateConstraints checks if the values respects the defined constraints +func AssertRegisteredModelCreateConstraints(obj model.RegisteredModelCreate) error { + return nil +} + +// AssertRegisteredModelRequired checks if the required fields are not zero-ed +func AssertRegisteredModelRequired(obj model.RegisteredModel) error { + return nil +} + +// AssertRegisteredModelConstraints checks if the values respects the defined constraints +func AssertRegisteredModelConstraints(obj model.RegisteredModel) error { + return nil +} + +// AssertRegisteredModelListRequired checks if the required fields are not zero-ed +func AssertRegisteredModelListRequired(obj model.RegisteredModelList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Items { + if err := AssertRegisteredModelRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertRegisteredModelListConstraints checks if the values respects the defined constraints +func AssertRegisteredModelListConstraints(obj model.RegisteredModelList) error { + return nil +} + +// AssertRegisteredModelUpdateRequired checks if the required fields are not zero-ed +func AssertRegisteredModelUpdateRequired(obj model.RegisteredModelUpdate) error { + return nil +} + +// AssertRegisteredModelUpdateConstraints checks if the values respects the defined constraints +func AssertRegisteredModelUpdateConstraints(obj model.RegisteredModelUpdate) error { + return nil +} + +// AssertServeModelCreateRequired checks if the required fields are not zero-ed +func AssertServeModelCreateRequired(obj model.ServeModelCreate) error { + elements := map[string]interface{}{ + "modelVersionId": obj.ModelVersionId, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertServeModelCreateConstraints checks if the values respects the defined constraints +func AssertServeModelCreateConstraints(obj model.ServeModelCreate) error { + return nil +} + +// AssertServeModelRequired checks if the required fields are not zero-ed +func AssertServeModelRequired(obj model.ServeModel) error { + elements := map[string]interface{}{ + "modelVersionId": obj.ModelVersionId, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertServeModelConstraints checks if the values respects the defined constraints +func AssertServeModelConstraints(obj model.ServeModel) error { + return nil +} + +// AssertServeModelListRequired checks if the required fields are not zero-ed +func AssertServeModelListRequired(obj model.ServeModelList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Items { + if err := AssertServeModelRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertServeModelListConstraints checks if the values respects the defined constraints +func AssertServeModelListConstraints(obj model.ServeModelList) error { + return nil +} + +// AssertServeModelUpdateRequired checks if the required fields are not zero-ed +func AssertServeModelUpdateRequired(obj model.ServeModelUpdate) error { + return nil +} + +// AssertServeModelUpdateConstraints checks if the values respects the defined constraints +func AssertServeModelUpdateConstraints(obj model.ServeModelUpdate) error { + return nil +} + +// AssertServingEnvironmentCreateRequired checks if the required fields are not zero-ed +func AssertServingEnvironmentCreateRequired(obj model.ServingEnvironmentCreate) error { + return nil +} + +// AssertServingEnvironmentCreateConstraints checks if the values respects the defined constraints +func AssertServingEnvironmentCreateConstraints(obj model.ServingEnvironmentCreate) error { + return nil +} + +// AssertServingEnvironmentRequired checks if the required fields are not zero-ed +func AssertServingEnvironmentRequired(obj model.ServingEnvironment) error { + return nil +} + +// AssertServingEnvironmentConstraints checks if the values respects the defined constraints +func AssertServingEnvironmentConstraints(obj model.ServingEnvironment) error { + return nil +} + +// AssertServingEnvironmentListRequired checks if the required fields are not zero-ed +func AssertServingEnvironmentListRequired(obj model.ServingEnvironmentList) error { + elements := map[string]interface{}{ + "nextPageToken": obj.NextPageToken, + "pageSize": obj.PageSize, + "size": obj.Size, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + for _, el := range obj.Items { + if err := AssertServingEnvironmentRequired(el); err != nil { + return err + } + } + return nil +} + +// AssertServingEnvironmentListConstraints checks if the values respects the defined constraints +func AssertServingEnvironmentListConstraints(obj model.ServingEnvironmentList) error { + return nil +} + +// AssertServingEnvironmentUpdateRequired checks if the required fields are not zero-ed +func AssertServingEnvironmentUpdateRequired(obj model.ServingEnvironmentUpdate) error { + return nil +} + +// AssertServingEnvironmentUpdateConstraints checks if the values respects the defined constraints +func AssertServingEnvironmentUpdateConstraints(obj model.ServingEnvironmentUpdate) error { + return nil +} + +// AssertSortOrderRequired checks if the required fields are not zero-ed +func AssertSortOrderRequired(obj model.SortOrder) error { + return nil +} + +// AssertSortOrderConstraints checks if the values respects the defined constraints +func AssertSortOrderConstraints(obj model.SortOrder) error { + return nil +} diff --git a/openapitools.json b/openapitools.json new file mode 100644 index 00000000..4053ae89 --- /dev/null +++ b/openapitools.json @@ -0,0 +1,7 @@ +{ + "$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json", + "spaces": 2, + "generator-cli": { + "version": "7.0.1" + } +} From 86204d45cea98c6c3ca18623559a1a5de76a4d00 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 20 Oct 2023 09:13:33 +0200 Subject: [PATCH 066/254] Implement MR service layer (#68) * Add service layer Co-authored-by: Matteo Mortari * Refactor service layer api Co-authored-by: Matteo Mortari * Adapt to refactored openapi models Co-authored-by: Matteo Mortari * Add ModelVersion API core impl and test update * Refactor core layer testing * Improve core testing * Cleanup comments * check put parent context error * cleanup readme * Correct terminology in tests * Using more explicit test-nocache on Makefile * Refactor core layer to make use of *List from openapi Co-authored-by: Andrea Lamparelli --------- Co-authored-by: Matteo Mortari --- Makefile | 4 + go.mod | 48 ++- go.sum | 143 +++++++- internal/core/api.go | 45 +++ internal/core/api_utils.go | 43 +++ internal/core/core.go | 456 +++++++++++++++++++++++++ internal/core/core_test.go | 198 +++++++++++ internal/core/mapper/mlmd_mapper.go | 263 ++++++++++++++ test/bdd/conn_config.pb | 6 + test/bdd/features/example.feature | 9 + test/bdd/mr_service_features_test.go | 228 +++++++++++++ test/config/ml-metadata/conn_config.pb | 6 + 12 files changed, 1445 insertions(+), 4 deletions(-) create mode 100644 internal/core/api.go create mode 100644 internal/core/api_utils.go create mode 100644 internal/core/core.go create mode 100644 internal/core/core_test.go create mode 100644 internal/core/mapper/mlmd_mapper.go create mode 100644 test/bdd/conn_config.pb create mode 100644 test/bdd/features/example.feature create mode 100644 test/bdd/mr_service_features_test.go create mode 100644 test/config/ml-metadata/conn_config.pb diff --git a/Makefile b/Makefile index 789e60db..6638beb6 100644 --- a/Makefile +++ b/Makefile @@ -119,6 +119,10 @@ lint: gen test: gen go test ./internal/... +.PHONY: test-nocache +test-nocache: gen + go test ./internal/... -count=1 + .PHONY: run/migrate run/migrate: gen go run main.go migrate --logtostderr=true -m config/metadata-library diff --git a/go.mod b/go.mod index 96c0acaa..e96d7555 100644 --- a/go.mod +++ b/go.mod @@ -12,8 +12,10 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.16.0 + github.com/stretchr/testify v1.8.4 + github.com/testcontainers/testcontainers-go v0.25.0 github.com/vektah/gqlparser/v2 v2.5.8 - golang.org/x/sync v0.2.0 + golang.org/x/sync v0.3.0 google.golang.org/grpc v1.57.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 @@ -23,29 +25,73 @@ require ( ) require ( + github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect + github.com/cucumber/messages/go/v21 v21.0.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/gofrs/uuid v4.3.1+incompatible // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-memdb v1.3.4 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect +) + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/hcsshim v0.11.0 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/containerd/containerd v1.7.6 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cucumber/godog v0.13.0 + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.6+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-ole/go-ole v1.2.6 // indirect + github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect + github.com/klauspost/compress v1.16.0 // indirect + github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/patternmatcher v0.5.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/term v0.5.0 // indirect + github.com/morikuni/aec v1.0.0 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/runc v1.1.5 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/searKing/golang/go v1.2.52 // indirect github.com/searKing/golang/tools v1.2.29 // indirect + github.com/shirou/gopsutil/v3 v3.23.8 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/subosito/gotenv v1.4.2 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/urfave/cli/v2 v2.25.5 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect diff --git a/go.sum b/go.sum index 938301e1..04a12840 100644 --- a/go.sum +++ b/go.sum @@ -35,38 +35,77 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/99designs/gqlgen v0.17.36 h1:u/o/rv2SZ9s5280dyUOOrkpIIkr/7kITMXYD3rkJ9go= github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= +github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= +github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= +github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= +github.com/cucumber/godog v0.13.0 h1:KvX9kNWmAJwp882HmObGOyBbNUP5SXQ+SDLNajsuV7A= +github.com/cucumber/godog v0.13.0/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces= +github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= +github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= +github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= +github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= @@ -75,6 +114,15 @@ github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNIT github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= @@ -117,7 +165,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -133,6 +183,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= @@ -140,8 +192,18 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 h1:2cz5kSrxzMYHiWOBbKj8itQm+nRykkB8aMv4ThcHYHA= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= +github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE= github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -156,28 +218,56 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/searKing/golang/go v1.2.52 h1:Nbsr8HIS4ATL7LY1BE3SwRyEQd+UkrRymyol46sXb3s= @@ -186,8 +276,19 @@ github.com/searKing/golang/tools v1.2.29 h1:gWX4aCA1+N7CfLpNd6tmBjYtecTksZFXziqb github.com/searKing/golang/tools v1.2.29/go.mod h1:QtwFM73H1qMKlRl0p8NRWXrNaCaffoYkNHk5YMoRyOY= github.com/searKing/golang/tools/go-enum v1.2.97 h1:mX396oCnjdGqmMmwffBwpEU3L1X/7K3eDuXOOLow+TQ= github.com/searKing/golang/tools/go-enum v1.2.97/go.mod h1:gWZ/vkIPpA0nCHDMETjzKqsHPDWSPdhZeXPxf/jWyqA= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= +github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= @@ -211,20 +312,35 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/testcontainers/testcontainers-go v0.25.0 h1:erH6cQjsaJrH+rJDU9qIf89KFdhK0Bft0aEZHlYC3Vs= +github.com/testcontainers/testcontainers-go v0.25.0/go.mod h1:4sC9SiJyzD1XFi59q8umTQYWxnkweEc5OjVtTUlJzqQ= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc= github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/vektah/gqlparser/v2 v2.5.8 h1:pm6WOnGdzFOCfcQo9L3+xzW51mKrlwTEg4Wr7AH1JW4= github.com/vektah/gqlparser/v2 v2.5.8/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -248,6 +364,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= +golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -327,8 +445,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= -golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -336,9 +454,13 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -358,13 +480,22 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -381,6 +512,7 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -418,6 +550,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -426,6 +559,7 @@ golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= @@ -530,12 +664,14 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -549,6 +685,7 @@ gorm.io/driver/sqlite v1.5.3 h1:7/0dUgX28KAcopdfbRWWl68Rflh6osa4rDh+m51KL2g= gorm.io/driver/sqlite v1.5.3/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/internal/core/api.go b/internal/core/api.go new file mode 100644 index 00000000..a88a899f --- /dev/null +++ b/internal/core/api.go @@ -0,0 +1,45 @@ +package core + +import "github.com/opendatahub-io/model-registry/internal/model/openapi" + +// Note: for convention, here we are keeping here adherence to the mlmd side +type BaseResourceId int64 + +type ListOptions struct { + PageSize *int32 + OrderBy *string + SortOrder *string + NextPageToken *string +} + +type ModelRegistryApi interface { + // REGISTERED MODEL + + // UpsertRegisteredModel create or update a registered model, the behavior follows the same + // approach used by MLMD gRPC api. If Id is provided update the entity otherwise create a new one. + UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) + + GetRegisteredModelById(id *BaseResourceId) (*openapi.RegisteredModel, error) + GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) + GetRegisteredModels(listOptions ListOptions) (*openapi.RegisteredModelList, error) + + // MODEL VERSION + + // Create a new Model Version + // or update a Model Version associated to a specific RegisteredModel identified by registeredModelId parameter + UpsertModelVersion(modelVersion *openapi.ModelVersion, registeredModelId *BaseResourceId) (*openapi.ModelVersion, error) + + GetModelVersionById(id *BaseResourceId) (*openapi.ModelVersion, error) + GetModelVersionByParams(name *string, externalId *string) (*openapi.ModelVersion, error) + GetModelVersions(listOptions ListOptions, registeredModelId *BaseResourceId) (*openapi.ModelVersionList, error) + + // MODEL ARTIFACT + + // Create or update a Model Artifact associated to a specific ModelVersion + // identified by ModelArtifact.ModelVersionId + UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *BaseResourceId) (*openapi.ModelArtifact, error) + + GetModelArtifactById(id *BaseResourceId) (*openapi.ModelArtifact, error) + GetModelArtifactByParams(name *string, externalId *string) (*openapi.ModelArtifact, error) + GetModelArtifacts(listOptions ListOptions, modelVersionId *BaseResourceId) (*openapi.ModelArtifactList, error) +} diff --git a/internal/core/api_utils.go b/internal/core/api_utils.go new file mode 100644 index 00000000..a3a4f010 --- /dev/null +++ b/internal/core/api_utils.go @@ -0,0 +1,43 @@ +package core + +import ( + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" +) + +func zeroIfNil[T any](input *T) T { + if input != nil { + return *input + } + return *new(T) +} + +func BuildListOperationOptions(listOptions ListOptions) (*proto.ListOperationOptions, error) { + + result := proto.ListOperationOptions{} + if listOptions.PageSize != nil { + result.MaxResultSize = listOptions.PageSize + } + if listOptions.NextPageToken != nil { + result.NextPageToken = listOptions.NextPageToken + } + if listOptions.OrderBy != nil { + so := listOptions.SortOrder + + // default is DESC + isAsc := false + if so != nil && *so == "ASC" { + isAsc = true + } + + var orderByField proto.ListOperationOptions_OrderByField_Field + if val, ok := proto.ListOperationOptions_OrderByField_Field_value[*listOptions.OrderBy]; ok { + orderByField = proto.ListOperationOptions_OrderByField_Field(val) + } + + result.OrderByField = &proto.ListOperationOptions_OrderByField{ + Field: &orderByField, + IsAsc: &isAsc, + } + } + return &result, nil +} diff --git a/internal/core/core.go b/internal/core/core.go new file mode 100644 index 00000000..e0cf9752 --- /dev/null +++ b/internal/core/core.go @@ -0,0 +1,456 @@ +package core + +import ( + "context" + "fmt" + "log" + "strconv" + + "github.com/opendatahub-io/model-registry/internal/core/mapper" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" + "google.golang.org/grpc" +) + +var ( + RegisteredModelTypeName = "odh.RegisteredModel" + ModelVersionTypeName = "odh.ModelVersion" + ModelArtifactTypeName = "odh.ModelArtifact" +) + +// modelRegistryService is the core library of the model registry +type modelRegistryService struct { + mlmdClient proto.MetadataStoreServiceClient + mapper *mapper.Mapper +} + +// NewModelRegistryService create a fresh instance of ModelRegistryService, taking care of setting up needed MLMD Types +func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, error) { + + client := proto.NewMetadataStoreServiceClient(cc) + + // Setup the needed Type instances if not existing already + + registeredModelReq := proto.PutContextTypeRequest{ + ContextType: &proto.ContextType{ + Name: &RegisteredModelTypeName, + }, + } + + modelVersionReq := proto.PutContextTypeRequest{ + ContextType: &proto.ContextType{ + Name: &ModelVersionTypeName, + Properties: map[string]proto.PropertyType{ + "model_name": proto.PropertyType_STRING, + "version": proto.PropertyType_STRING, + "author": proto.PropertyType_STRING, + }, + }, + } + + modelArtifactReq := proto.PutArtifactTypeRequest{ + ArtifactType: &proto.ArtifactType{ + Name: &ModelArtifactTypeName, + Properties: map[string]proto.PropertyType{ + "model_format": proto.PropertyType_STRING, + }, + }, + } + + registeredModelResp, err := client.PutContextType(context.Background(), ®isteredModelReq) + if err != nil { + log.Fatalf("Error setting up context type %s: %v", RegisteredModelTypeName, err) + } + + modelVersionResp, err := client.PutContextType(context.Background(), &modelVersionReq) + if err != nil { + log.Fatalf("Error setting up context type %s: %v", ModelVersionTypeName, err) + } + modelArtifactResp, err := client.PutArtifactType(context.Background(), &modelArtifactReq) + if err != nil { + log.Fatalf("Error setting up artifact type %s: %v", ModelArtifactTypeName, err) + } + + return &modelRegistryService{ + mlmdClient: client, + mapper: mapper.NewMapper(registeredModelResp.GetTypeId(), modelVersionResp.GetTypeId(), modelArtifactResp.GetTypeId()), + }, nil +} + +// REGISTERED MODELS + +func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) { + log.Printf("Creating or updating registered model for %s", *registeredModel.Name) + + modelCtx, err := serv.mapper.MapFromRegisteredModel(registeredModel) + if err != nil { + return nil, err + } + + modelCtxResp, err := serv.mlmdClient.PutContexts(context.Background(), &proto.PutContextsRequest{ + Contexts: []*proto.Context{ + modelCtx, + }, + }) + if err != nil { + return nil, err + } + + modelId := &modelCtxResp.ContextIds[0] + model, err := serv.GetRegisteredModelById((*BaseResourceId)(modelId)) + if err != nil { + return nil, err + } + + return model, nil +} + +func (serv *modelRegistryService) GetRegisteredModelById(id *BaseResourceId) (*openapi.RegisteredModel, error) { + log.Printf("Getting registered model %d", *id) + + getByIdResp, err := serv.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{int64(*id)}, + }) + if err != nil { + return nil, err + } + + if len(getByIdResp.Contexts) != 1 { + return nil, fmt.Errorf("multiple registered models found for id %d", *id) + } + + regModel, err := serv.mapper.MapToRegisteredModel(getByIdResp.Contexts[0]) + if err != nil { + return nil, err + } + + return regModel, nil +} + +func (serv *modelRegistryService) GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) { + log.Printf("Getting registered model by params name=%v, externalId=%v", name, externalId) + + filterQuery := "" + if name != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", *name) + } else if externalId != nil { + filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) + } + + getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: &RegisteredModelTypeName, + Options: &proto.ListOperationOptions{ + FilterQuery: &filterQuery, + }, + }) + if err != nil { + return nil, err + } + + if len(getByParamsResp.Contexts) != 1 { + return nil, fmt.Errorf("multiple registered models found for name=%v, externalId=%v", *name, *externalId) + } + + regModel, err := serv.mapper.MapToRegisteredModel(getByParamsResp.Contexts[0]) + if err != nil { + return nil, err + } + return regModel, nil +} + +func (serv *modelRegistryService) GetRegisteredModels(listOptions ListOptions) (*openapi.RegisteredModelList, error) { + listOperationOptions, err := BuildListOperationOptions(listOptions) + if err != nil { + return nil, err + } + contextsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: &RegisteredModelTypeName, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + + results := []openapi.RegisteredModel{} + for _, c := range contextsResp.Contexts { + mapped, err := serv.mapper.MapToRegisteredModel(c) + if err != nil { + return nil, err + } + results = append(results, *mapped) + } + + toReturn := openapi.RegisteredModelList{ + NextPageToken: zeroIfNil(contextsResp.NextPageToken), + PageSize: zeroIfNil(listOptions.PageSize), + Size: int32(len(results)), + Items: results, + } + return &toReturn, nil +} + +// MODEL VERSIONS + +func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, registeredModelId *BaseResourceId) (*openapi.ModelVersion, error) { + registeredModel, err := serv.GetRegisteredModelById(registeredModelId) + if err != nil { + return nil, fmt.Errorf("not a valid registered model id: %d", *registeredModelId) + } + registeredModelIdCtxID, err := mapper.IdToInt64(*registeredModel.Id) + if err != nil { + return nil, err + } + registeredModelName := registeredModel.Name + modelCtx, err := serv.mapper.MapFromModelVersion(modelVersion, *registeredModelIdCtxID, registeredModelName) + if err != nil { + return nil, err + } + + modelCtxResp, err := serv.mlmdClient.PutContexts(context.Background(), &proto.PutContextsRequest{ + Contexts: []*proto.Context{ + modelCtx, + }, + }) + if err != nil { + return nil, err + } + + modelId := &modelCtxResp.ContextIds[0] + _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ + ParentContexts: []*proto.ParentContext{{ + ChildId: modelId, + ParentId: registeredModelIdCtxID}}, + TransactionOptions: &proto.TransactionOptions{}, + }) + if err != nil { + return nil, err + } + + model, err := serv.GetModelVersionById((*BaseResourceId)(modelId)) + if err != nil { + return nil, err + } + + return model, nil +} + +func (serv *modelRegistryService) GetModelVersionById(id *BaseResourceId) (*openapi.ModelVersion, error) { + getByIdResp, err := serv.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{int64(*id)}, + }) + if err != nil { + return nil, err + } + + if len(getByIdResp.Contexts) != 1 { + return nil, fmt.Errorf("multiple model versions found for id %d", *id) + } + + modelVer, err := serv.mapper.MapToModelVersion(getByIdResp.Contexts[0]) + if err != nil { + return nil, err + } + + return modelVer, nil +} + +func (serv *modelRegistryService) GetModelVersionByParams(name *string, externalId *string) (*openapi.ModelVersion, error) { + filterQuery := "" + if name != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", *name) + } else if externalId != nil { + filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) + } + + getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: &ModelVersionTypeName, + Options: &proto.ListOperationOptions{ + FilterQuery: &filterQuery, + }, + }) + if err != nil { + return nil, err + } + + if len(getByParamsResp.Contexts) != 1 { + return nil, fmt.Errorf("multiple registered models found for name=%v, externalId=%v", *name, *externalId) + } + + modelVer, err := serv.mapper.MapToModelVersion(getByParamsResp.Contexts[0]) + if err != nil { + return nil, err + } + return modelVer, nil +} + +func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, registeredModelId *BaseResourceId) (*openapi.ModelVersionList, error) { + listOperationOptions, err := BuildListOperationOptions(listOptions) + if err != nil { + return nil, err + } + + if registeredModelId != nil { + queryParentCtxId := fmt.Sprintf("parent_contexts_a.type = %d", *registeredModelId) + listOperationOptions.FilterQuery = &queryParentCtxId + } + + contextsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: &ModelVersionTypeName, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + + results := []openapi.ModelVersion{} + for _, c := range contextsResp.Contexts { + mapped, err := serv.mapper.MapToModelVersion(c) + if err != nil { + return nil, err + } + results = append(results, *mapped) + } + + toReturn := openapi.ModelVersionList{ + NextPageToken: zeroIfNil(contextsResp.NextPageToken), + PageSize: zeroIfNil(listOptions.PageSize), + Size: int32(len(results)), + Items: results, + } + return &toReturn, nil +} + +// MODEL ARTIFACTS + +func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *BaseResourceId) (*openapi.ModelArtifact, error) { + artifact := serv.mapper.MapFromModelArtifact(*modelArtifact) + + artifactsResp, err := serv.mlmdClient.PutArtifacts(context.Background(), &proto.PutArtifactsRequest{ + Artifacts: []*proto.Artifact{artifact}, + }) + if err != nil { + return nil, err + } + idString := strconv.FormatInt(artifactsResp.ArtifactIds[0], 10) + modelArtifact.Id = &idString + + // add explicit association between artifacts and model version + if modelVersionId != nil { + modelVersionIdCtx := int64(*modelVersionId) + attributions := []*proto.Attribution{} + for _, a := range artifactsResp.ArtifactIds { + attributions = append(attributions, &proto.Attribution{ + ContextId: &modelVersionIdCtx, + ArtifactId: &a, + }) + } + _, err = serv.mlmdClient.PutAttributionsAndAssociations(context.Background(), &proto.PutAttributionsAndAssociationsRequest{ + Attributions: attributions, + Associations: make([]*proto.Association, 0), + }) + if err != nil { + return nil, err + } + } + + return modelArtifact, nil +} + +func (serv *modelRegistryService) GetModelArtifactById(id *BaseResourceId) (*openapi.ModelArtifact, error) { + artifactsResp, err := serv.mlmdClient.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ + ArtifactIds: []int64{int64(*id)}, + }) + if err != nil { + return nil, err + } + + result, err := serv.mapper.MapToModelArtifact(artifactsResp.Artifacts[0]) + if err != nil { + return nil, err + } + + return result, nil +} + +func (serv *modelRegistryService) GetModelArtifactByParams(name *string, externalId *string) (*openapi.ModelArtifact, error) { + var artifact0 *proto.Artifact + + filterQuery := "" + if externalId != nil { + filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) + } else if name != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", *name) + } else { + return nil, fmt.Errorf("invalid parameters call, supply either name or externalId") + } + + artifactsResponse, err := serv.mlmdClient.GetArtifactsByType(context.Background(), &proto.GetArtifactsByTypeRequest{ + TypeName: &ModelArtifactTypeName, + Options: &proto.ListOperationOptions{ + FilterQuery: &filterQuery, + }, + }) + if err != nil { + return nil, err + } + if len(artifactsResponse.Artifacts) > 1 { + return nil, fmt.Errorf("more than an artifact detected matching criteria: %v", artifactsResponse.Artifacts) + } + artifact0 = artifactsResponse.Artifacts[0] + + result, err := serv.mapper.MapToModelArtifact(artifact0) + if err != nil { + return nil, err + } + + return result, nil +} + +func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, modelVersionId *BaseResourceId) (*openapi.ModelArtifactList, error) { + listOperationOptions, err := BuildListOperationOptions(listOptions) + if err != nil { + return nil, err + } + + var artifacts []*proto.Artifact + var nextPageToken *string + if modelVersionId != nil { + ctxId := int64(*modelVersionId) + artifactsResp, err := serv.mlmdClient.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ + ContextId: &ctxId, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + artifacts = artifactsResp.Artifacts + nextPageToken = artifactsResp.NextPageToken + } else { + artifactsResp, err := serv.mlmdClient.GetArtifactsByType(context.Background(), &proto.GetArtifactsByTypeRequest{ + TypeName: &ModelArtifactTypeName, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + artifacts = artifactsResp.Artifacts + nextPageToken = artifactsResp.NextPageToken + } + + results := []openapi.ModelArtifact{} + for _, a := range artifacts { + mapped, err := serv.mapper.MapToModelArtifact(a) + if err != nil { + return nil, err + } + results = append(results, *mapped) + } + + toReturn := openapi.ModelArtifactList{ + NextPageToken: zeroIfNil(nextPageToken), + PageSize: zeroIfNil(listOptions.PageSize), + Size: int32(len(results)), + Items: results, + } + return &toReturn, nil +} diff --git a/internal/core/core_test.go b/internal/core/core_test.go new file mode 100644 index 00000000..dfb5c3d1 --- /dev/null +++ b/internal/core/core_test.go @@ -0,0 +1,198 @@ +package core_test + +import ( + "context" + "fmt" + "os" + "testing" + + "github.com/opendatahub-io/model-registry/internal/core" + "github.com/opendatahub-io/model-registry/internal/core/mapper" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/stretchr/testify/assert" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + useProvider = testcontainers.ProviderDefault // or explicit to testcontainers.ProviderPodman if needed + mlmdImage = "gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0" + sqliteFile = "metadata.sqlite.db" + testConfigFolder = "test/config/ml-metadata" +) + +func TestCreateRegisteredModel(t *testing.T) { + conn, client, teardown := SetupTestContainer(t) + defer teardown(t) + + // [TEST CASE] + + // create mode registry service + service, err := core.NewModelRegistryService(conn) + assert.Nilf(t, err, "error creating core service: %v", err) + + modelName := "PricingModel" + externalId := "myExternalId" + owner := "Myself" + + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &externalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataValueOneOf2: &openapi.MetadataValueOneOf2{ + StringValue: &owner, + }, + }, + }, + } + + // test + createdModel, err := service.UpsertRegisteredModel(registeredModel) + + // checks + assert.Nilf(t, err, "error creating registered model: %v", err) + assert.NotNilf(t, createdModel.Id, "created registered model should not have nil Id") + + byTypeAndNameResp, err := client.GetContextByTypeAndName(context.Background(), &proto.GetContextByTypeAndNameRequest{ + TypeName: &core.RegisteredModelTypeName, + ContextName: &modelName, + }) + assert.Nilf(t, err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctxId := mapper.IdToString(*byTypeAndNameResp.Context.Id) + assert.Equal(t, *createdModel.Id, *ctxId, "returned model id should match the mlmd one") + assert.Equal(t, modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") + assert.Equal(t, externalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") + assert.Equal(t, owner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assert.Nilf(t, err, "error retrieving all contexts, not related to the test itself: %v", err) + assert.Equal(t, 1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") +} + +func TestGetRegisteredModelById(t *testing.T) { + conn, _, teardown := SetupTestContainer(t) + defer teardown(t) + + // [TEST CASE] + + // create mode registry service + service, err := core.NewModelRegistryService(conn) + assert.Nilf(t, err, "error creating core service: %v", err) + + modelName := "PricingModel" + externalId := "mysupermodel" + + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &externalId, + } + + // test + createdModel, err := service.UpsertRegisteredModel(registeredModel) + + // checks + assert.Nilf(t, err, "error creating registered model: %v", err) + + modelId, _ := mapper.IdToInt64(*createdModel.Id) + getModelById, err := service.GetRegisteredModelById((*core.BaseResourceId)(modelId)) + assert.Nilf(t, err, "error getting registered model by id %d: %v", *modelId, err) + + assert.Equal(t, modelName, *getModelById.Name, "saved model name should match the provided one") + assert.Equal(t, externalId, *getModelById.ExternalID, "saved external id should match the provided one") +} + +// ################# +// ##### Utils ##### +// ################# + +func clearMetadataSqliteDB(wd string) error { + if err := os.Remove(fmt.Sprintf("%s/%s", wd, sqliteFile)); err != nil { + return fmt.Errorf("expected to clear sqlite file but didn't find: %v", err) + } + return nil +} + +// SetupTestContainer creates a MLMD gRPC test container +// Returns +// - gRPC client connection to the test container +// - ml-metadata client used to double check the database +// - teardown function +func SetupTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { + ctx := context.Background() + wd, err := os.Getwd() + if err != nil { + t.Errorf("error getting working directory: %v", err) + } + wd = fmt.Sprintf("%s/../../%s", wd, testConfigFolder) + t.Logf("using working directory: %s", wd) + + req := testcontainers.ContainerRequest{ + Image: mlmdImage, + ExposedPorts: []string{"8080/tcp"}, + Env: map[string]string{ + "METADATA_STORE_SERVER_CONFIG_FILE": "/tmp/shared/conn_config.pb", + }, + Mounts: testcontainers.ContainerMounts{ + testcontainers.ContainerMount{ + Source: testcontainers.GenericBindMountSource{ + HostPath: wd, + }, + Target: "/tmp/shared", + }, + }, + WaitingFor: wait.ForLog("Server listening on"), + } + + mlmdgrpc, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ProviderType: useProvider, + ContainerRequest: req, + Started: true, + }) + if err != nil { + t.Errorf("error setting up mlmd grpc container: %v", err) + } + + mappedHost, err := mlmdgrpc.Host(ctx) + if err != nil { + t.Error(err) + } + mappedPort, err := mlmdgrpc.MappedPort(ctx, "8080") + if err != nil { + t.Error(err) + } + mlmdAddr := fmt.Sprintf("%s:%s", mappedHost, mappedPort.Port()) + t.Log("MLMD test container setup at: ", mlmdAddr) + + // setup grpc connection + conn, err := grpc.DialContext( + context.Background(), + mlmdAddr, + grpc.WithReturnConnectionError(), + grpc.WithBlock(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + t.Errorf("error dialing connection to mlmd server %s: %v", mlmdAddr, err) + } + + mlmdClient := proto.NewMetadataStoreServiceClient(conn) + + return conn, mlmdClient, func(t *testing.T) { + if err := conn.Close(); err != nil { + t.Error(err) + } + if err := mlmdgrpc.Terminate(ctx); err != nil { + t.Error(err) + } + if err := clearMetadataSqliteDB(wd); err != nil { + t.Error(err) + } + } +} diff --git a/internal/core/mapper/mlmd_mapper.go b/internal/core/mapper/mlmd_mapper.go new file mode 100644 index 00000000..a657d0de --- /dev/null +++ b/internal/core/mapper/mlmd_mapper.go @@ -0,0 +1,263 @@ +package mapper + +import ( + "fmt" + "log" + "strconv" + + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +type Mapper struct { + RegisteredModelTypeId int64 + ModelVersionTypeId int64 + ModelArtifactTypeId int64 +} + +func NewMapper(registeredModelTypeId int64, modelVersionTypeId int64, modelArtifactTypeId int64) *Mapper { + return &Mapper{ + RegisteredModelTypeId: registeredModelTypeId, + ModelVersionTypeId: modelVersionTypeId, + ModelArtifactTypeId: modelArtifactTypeId, + } +} + +func IdToInt64(idString string) (*int64, error) { + idInt, err := strconv.Atoi(idString) + if err != nil { + return nil, err + } + + idInt64 := int64(idInt) + + return &idInt64, nil +} + +func IdToString(idInt int64) *string { + idString := strconv.FormatInt(idInt, 10) + + return &idString +} + +// Internal Model --> MLMD + +// Map generic map into MLMD [custom] properties object +func (m *Mapper) MapToProperties(data map[string]openapi.MetadataValue) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + + for key, v := range data { + value := proto.Value{} + + switch { + // int value + case v.MetadataValueOneOf != nil: + intValue, err := IdToInt64(*v.MetadataValueOneOf.IntValue) + if err != nil { + log.Printf("Skipping mapping for %s:%v", key, v) + continue + } + value.Value = &proto.Value_IntValue{IntValue: *intValue} + // double value + case v.MetadataValueOneOf1 != nil: + value.Value = &proto.Value_DoubleValue{DoubleValue: *v.MetadataValueOneOf1.DoubleValue} + // double value + case v.MetadataValueOneOf2 != nil: + value.Value = &proto.Value_StringValue{StringValue: *v.MetadataValueOneOf2.StringValue} + default: + log.Printf("Type mapping not found for %s:%v", key, v) + continue + } + + props[key] = &value + } + + return props, nil +} + +func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel) (*proto.Context, error) { + + var idInt *int64 + if registeredModel.Id != nil { + var err error + idInt, err = IdToInt64(*registeredModel.Id) + if err != nil { + return nil, err + } + } + + customProps := make(map[string]*proto.Value) + if registeredModel.CustomProperties != nil { + customProps, _ = m.MapToProperties(*registeredModel.CustomProperties) + } + + return &proto.Context{ + Name: registeredModel.Name, + TypeId: &m.RegisteredModelTypeId, + ExternalId: registeredModel.ExternalID, + Id: idInt, + CustomProperties: customProps, + }, nil +} + +func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registeredModelId int64, registeredModelName *string) (*proto.Context, error) { + fullName := fmt.Sprintf("%d:%s", registeredModelId, *modelVersion.Name) + customProps := make(map[string]*proto.Value) + if modelVersion.CustomProperties != nil { + customProps, _ = m.MapToProperties(*modelVersion.CustomProperties) + } + ctx := &proto.Context{ + Name: &fullName, + TypeId: &m.ModelVersionTypeId, + Properties: map[string]*proto.Value{ + "model_name": { + Value: &proto.Value_StringValue{ + StringValue: *registeredModelName, + }, + }, + }, + CustomProperties: customProps, + } + if modelVersion.Name != nil { + ctx.Properties["version"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *modelVersion.Name, + }, + } + } + // TODO: missing explicit property in openapi + // if modelVersion.Author != nil { + // ctx.Properties["author"] = &proto.Value{ + // Value: &proto.Value_StringValue{ + // StringValue: *modelVersion.Author, + // }, + // } + // } + + return ctx, nil +} + +func (m *Mapper) MapFromModelArtifact(modelArtifact openapi.ModelArtifact) *proto.Artifact { + return &proto.Artifact{ + TypeId: &m.ModelArtifactTypeId, + // TODO: we should use concatenation between uuid + name + Name: modelArtifact.Name, + Uri: modelArtifact.Uri, + } +} + +func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact) ([]*proto.Artifact, error) { + artifacts := []*proto.Artifact{} + if modelArtifacts == nil { + return artifacts, nil + } + for _, a := range *modelArtifacts { + artifacts = append(artifacts, m.MapFromModelArtifact(a)) + } + return artifacts, nil +} + +// MLMD --> Internal Model + +// Maps MLMD properties into a generic map +func (m *Mapper) MapFromProperties(props map[string]*proto.Value) (map[string]openapi.MetadataValue, error) { + data := make(map[string]openapi.MetadataValue) + + for key, v := range props { + // data[key] = v.Value + customValue := openapi.MetadataValue{} + + switch typedValue := v.Value.(type) { + case *proto.Value_IntValue: + customValue.MetadataValueOneOf = &openapi.MetadataValueOneOf{ + IntValue: IdToString(typedValue.IntValue), + } + case *proto.Value_DoubleValue: + customValue.MetadataValueOneOf1 = &openapi.MetadataValueOneOf1{ + DoubleValue: &typedValue.DoubleValue, + } + case *proto.Value_StringValue: + customValue.MetadataValueOneOf2 = &openapi.MetadataValueOneOf2{ + StringValue: &typedValue.StringValue, + } + default: + log.Printf("Type mapping not found for %s:%v", key, v) + continue + } + + data[key] = customValue + } + + return data, nil +} + +func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredModel, error) { + if ctx.GetTypeId() != m.RegisteredModelTypeId { + return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.RegisteredModelTypeId, ctx.GetTypeId()) + } + + _, err := m.MapFromProperties(ctx.CustomProperties) + if err != nil { + return nil, err + } + + idString := strconv.FormatInt(*ctx.Id, 10) + + model := &openapi.RegisteredModel{ + Id: &idString, + Name: ctx.Name, + ExternalID: ctx.ExternalId, + } + + return model, nil +} + +func (m *Mapper) MapToModelVersion(ctx *proto.Context) (*openapi.ModelVersion, error) { + if ctx.GetTypeId() != m.ModelVersionTypeId { + return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.ModelVersionTypeId, ctx.GetTypeId()) + } + + metadata, err := m.MapFromProperties(ctx.CustomProperties) + if err != nil { + return nil, err + } + + // modelName := ctx.GetProperties()["model_name"].GetStringValue() + // version := ctx.GetProperties()["version"].GetStringValue() + // author := ctx.GetProperties()["author"].GetStringValue() + + idString := strconv.FormatInt(*ctx.Id, 10) + + modelVersion := &openapi.ModelVersion{ + // ModelName: &modelName, + Id: &idString, + Name: ctx.Name, + // Author: &author, + CustomProperties: &metadata, + } + + return modelVersion, nil +} + +func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArtifact, error) { + if artifact.GetTypeId() != m.ModelArtifactTypeId { + return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.ModelArtifactTypeId, artifact.GetTypeId()) + } + + _, err := m.MapFromProperties(artifact.CustomProperties) + if err != nil { + return nil, err + } + + _, err = m.MapFromProperties(artifact.Properties) + if err != nil { + return nil, err + } + + modelArtifact := &openapi.ModelArtifact{ + Uri: artifact.Uri, + Name: artifact.Name, + } + + return modelArtifact, nil +} diff --git a/test/bdd/conn_config.pb b/test/bdd/conn_config.pb new file mode 100644 index 00000000..774b7aa0 --- /dev/null +++ b/test/bdd/conn_config.pb @@ -0,0 +1,6 @@ +connection_config { + sqlite { + filename_uri: '/tmp/shared/metadata.sqlite.db' + connection_mode: READWRITE_OPENCREATE + } +} diff --git a/test/bdd/features/example.feature b/test/bdd/features/example.feature new file mode 100644 index 00000000..70049726 --- /dev/null +++ b/test/bdd/features/example.feature @@ -0,0 +1,9 @@ +Feature: As a MLOps engineer I would like the Model Registry to store metadata information about models + Taken from User Stories + + Scenario: As a MLOps engineer I would like to store Model name + Given I have a connection to MR + When I store a RegisteredModel with name "Pricing Model" and a child ModelVersion with name "v1" and a child Artifact with uri "s3://12345" + Then there should be a mlmd Context of type "odh.RegisteredModel" named "Pricing Model" + And there should be a mlmd Context of type "odh.ModelVersion" having property named "model_name" valorised with string value "Pricing Model" + diff --git a/test/bdd/mr_service_features_test.go b/test/bdd/mr_service_features_test.go new file mode 100644 index 00000000..5def7f11 --- /dev/null +++ b/test/bdd/mr_service_features_test.go @@ -0,0 +1,228 @@ +package bdd_test + +import ( + "context" + "fmt" + "log" + "os" + "strconv" + "testing" + + "github.com/cucumber/godog" + "github.com/opendatahub-io/model-registry/internal/core" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const useProvider = testcontainers.ProviderDefault // or explicit to testcontainers.ProviderPodman if needed + +var ( + mlmdHostname string + mlmdPort int +) + +func TestFeatures(t *testing.T) { + suite := godog.TestSuite{ + ScenarioInitializer: InitializeScenario, + Options: &godog.Options{ + Format: "pretty", + Paths: []string{"features"}, + TestingT: t, // Testing instance that will run subtests. + }, + } + + if suite.Run() != 0 { + t.Fatal("non-zero status returned, failed to run feature tests") + } +} + +type wdCtxKey struct{} +type testContainerCtxKey struct{} +type svcLayerCtxKey struct{} +type connCtxKey struct{} + +func iHaveAConnectionToMR(ctx context.Context) (context.Context, error) { + mlmdAddr := fmt.Sprintf("%s:%d", mlmdHostname, mlmdPort) + conn, err := grpc.DialContext( + context.Background(), + mlmdAddr, + grpc.WithReturnConnectionError(), + grpc.WithBlock(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + log.Fatalf("Error dialing connection to mlmd server %s: %v", mlmdAddr, err) + return nil, err + } + ctx = context.WithValue(ctx, connCtxKey{}, conn) + service, err := core.NewModelRegistryService(conn) + if err != nil { + log.Fatalf("Error creating core service: %v", err) + return nil, err + } + return context.WithValue(ctx, svcLayerCtxKey{}, service), nil +} + +func iStoreARegisteredModelWithNameAndAChildModelVersionWithNameAndAChildArtifactWithUri(ctx context.Context, registedModelName, modelVersionName, artifactURI string) error { + service, ok := ctx.Value(svcLayerCtxKey{}).(core.ModelRegistryApi) + if !ok { + return fmt.Errorf("not found service layer connection in godog context") + } + var registeredModel *openapi.RegisteredModel + var err error + registeredModel, err = service.UpsertRegisteredModel(&openapi.RegisteredModel{ + Name: ®istedModelName, + }) + if err != nil { + return err + } + registeredModelId, err := idToInt64(*registeredModel.Id) + if err != nil { + return err + } + + var modelVersion *openapi.ModelVersion + if modelVersion, err = service.UpsertModelVersion(&openapi.ModelVersion{Name: &modelVersionName}, (*core.BaseResourceId)(registeredModelId)); err != nil { + return err + } + modelVersionId, err := idToInt64(*modelVersion.Id) + if err != nil { + return err + } + + if _, err = service.UpsertModelArtifact(&openapi.ModelArtifact{Uri: &artifactURI}, (*core.BaseResourceId)(modelVersionId)); err != nil { + return err + } + + return nil +} + +func idToInt64(idString string) (*int64, error) { + idInt, err := strconv.Atoi(idString) + if err != nil { + return nil, err + } + + idInt64 := int64(idInt) + + return &idInt64, nil +} + +func thereShouldBeAMlmdContextOfTypeNamed(ctx context.Context, arg1, arg2 string) error { + conn := ctx.Value(connCtxKey{}).(*grpc.ClientConn) + client := proto.NewMetadataStoreServiceClient(conn) + query := fmt.Sprintf("type = \"%s\" and name = \"%s\"", arg1, arg2) + fmt.Println("query: ", query) + resp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{ + Options: &proto.ListOperationOptions{ + FilterQuery: &query, + }, + }) + if err != nil { + return err + } + if len(resp.Contexts) != 1 { + return fmt.Errorf("Unexpected mlmd Context result size (%d), %v", len(resp.Contexts), resp.Contexts) + } + return nil +} + +func thereShouldBeAMlmdContextOfTypeHavingPropertyNamedValorisedWithStringValue(ctx context.Context, arg1, arg2, arg3 string) error { + conn := ctx.Value(connCtxKey{}).(*grpc.ClientConn) + client := proto.NewMetadataStoreServiceClient(conn) + query := fmt.Sprintf("type = \"%s\" and properties.%s.string_value = \"%s\"", arg1, arg2, arg3) + fmt.Println("query: ", query) + resp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{ + Options: &proto.ListOperationOptions{ + FilterQuery: &query, + }, + }) + if err != nil { + return err + } + if len(resp.Contexts) != 1 { + return fmt.Errorf("Unexpected mlmd Context result size (%d), %v", len(resp.Contexts), resp.Contexts) + } + return nil +} + +func InitializeScenario(ctx *godog.ScenarioContext) { + ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) { + wd, mlmdgrpc, err := setupTestContainer(ctx) + if err != nil { + return ctx, err + } + ctx = context.WithValue(ctx, wdCtxKey{}, wd) + ctx = context.WithValue(ctx, testContainerCtxKey{}, mlmdgrpc) + mappedHost, err := mlmdgrpc.Host(ctx) + if err != nil { + return ctx, err + } + mappedPort, err := mlmdgrpc.MappedPort(ctx, "8080") + if err != nil { + return ctx, err + } + // TODO: these are effectively global in main and could be worthy to revisit + mlmdHostname = mappedHost + mlmdPort = mappedPort.Int() + return ctx, nil + }) + ctx.Step(`^I have a connection to MR$`, iHaveAConnectionToMR) + ctx.Step(`^I store a RegisteredModel with name "([^"]*)" and a child ModelVersion with name "([^"]*)" and a child Artifact with uri "([^"]*)"$`, iStoreARegisteredModelWithNameAndAChildModelVersionWithNameAndAChildArtifactWithUri) + ctx.Step(`^there should be a mlmd Context of type "([^"]*)" named "([^"]*)"$`, thereShouldBeAMlmdContextOfTypeNamed) + ctx.Step(`^there should be a mlmd Context of type "([^"]*)" having property named "([^"]*)" valorised with string value "([^"]*)"$`, thereShouldBeAMlmdContextOfTypeHavingPropertyNamedValorisedWithStringValue) + ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) { + conn := ctx.Value(connCtxKey{}).(*grpc.ClientConn) + conn.Close() + mlmdgrpc := ctx.Value(testContainerCtxKey{}).(testcontainers.Container) + if err := mlmdgrpc.Terminate(ctx); err != nil { + return ctx, err + } + wd := ctx.Value(wdCtxKey{}).(string) + clearMetadataSqliteDB(wd) + return ctx, nil + }) +} + +func clearMetadataSqliteDB(wd string) error { + if err := os.Remove(fmt.Sprintf("%s/%s", wd, "metadata.sqlite.db")); err != nil { + return fmt.Errorf("Expected to clear sqlite file but didn't find: %v", err) + } + return nil +} + +func setupTestContainer(ctx context.Context) (string, testcontainers.Container, error) { + wd, err := os.Getwd() + if err != nil { + return "", nil, err + } + req := testcontainers.ContainerRequest{ + Image: "gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0", + ExposedPorts: []string{"8080/tcp"}, + Env: map[string]string{ + "METADATA_STORE_SERVER_CONFIG_FILE": "/tmp/shared/conn_config.pb", + }, + Mounts: testcontainers.ContainerMounts{ + testcontainers.ContainerMount{ + Source: testcontainers.GenericBindMountSource{ + HostPath: wd, + }, + Target: "/tmp/shared", + }, + }, + WaitingFor: wait.ForLog("Server listening on"), + } + mlmdgrpc, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ProviderType: useProvider, + ContainerRequest: req, + Started: true, + }) + if err != nil { + return "", nil, err + } + return wd, mlmdgrpc, nil +} diff --git a/test/config/ml-metadata/conn_config.pb b/test/config/ml-metadata/conn_config.pb new file mode 100644 index 00000000..774b7aa0 --- /dev/null +++ b/test/config/ml-metadata/conn_config.pb @@ -0,0 +1,6 @@ +connection_config { + sqlite { + filename_uri: '/tmp/shared/metadata.sqlite.db' + connection_mode: READWRITE_OPENCREATE + } +} From 89af1567177c0206da8038f9c59d2ac5335ff853 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 20 Oct 2023 01:35:10 -0700 Subject: [PATCH 067/254] Fix MetadataValue to use named property value types, add registeredModelID query param (#75) * Fix MetadataValue to use named property value types * Add registeredModelID query parameter for ModelVersion search * Wire OpenAPI Metadata changes in core mapper --------- Co-authored-by: tarilabs --- api/openapi/model-registry.yaml | 146 ++++++++------ internal/core/core_test.go | 2 +- internal/core/mapper/mlmd_mapper.go | 20 +- .../model/openapi/.openapi-generator/FILES | 12 +- .../openapi/api_model_registry_service.go | 18 +- ...e_of_5.go => model_metadata_bool_value.go} | 52 ++--- ...of_1.go => model_metadata_double_value.go} | 52 ++--- ..._one_of.go => model_metadata_int_value.go} | 52 ++--- ..._of_4.go => model_metadata_proto_value.go} | 60 +++--- ...of_2.go => model_metadata_string_value.go} | 52 ++--- ...of_3.go => model_metadata_struct_value.go} | 52 ++--- .../model/openapi/model_metadata_value.go | 180 +++++++++--------- .../server/openapi/.openapi-generator/FILES | 48 ----- internal/server/openapi/api.go | 2 +- .../openapi/api_model_registry_service.go | 5 +- .../api_model_registry_service_service.go | 2 +- internal/server/openapi/type_asserts.go | 21 -- 17 files changed, 374 insertions(+), 402 deletions(-) rename internal/model/openapi/{model_metadata_value_one_of_5.go => model_metadata_bool_value.go} (54%) rename internal/model/openapi/{model_metadata_value_one_of_1.go => model_metadata_double_value.go} (56%) rename internal/model/openapi/{model_metadata_value_one_of.go => model_metadata_int_value.go} (55%) rename internal/model/openapi/{model_metadata_value_one_of_4.go => model_metadata_proto_value.go} (59%) rename internal/model/openapi/{model_metadata_value_one_of_2.go => model_metadata_string_value.go} (56%) rename internal/model/openapi/{model_metadata_value_one_of_3.go => model_metadata_struct_value.go} (57%) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index a051b89c..bb065ca9 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -372,33 +372,6 @@ paths: type: string in: path required: true - /api/model_registry/v1alpha1/model_version: - summary: Path used to search for a modelversion. - description: >- - The REST endpoint/path used to search for a `ModelVersion` entity. This path contains a `GET` - operation to perform the find task. - get: - tags: - - ModelRegistryService - responses: - '200': - $ref: '#/components/responses/ModelVersionResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' - operationId: findModelVersion - summary: Get a ModelVersion that matches search parameters. - description: Gets the details of a single instance of a `ModelVersion` that matches search parameters. - parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' '/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts': summary: Path used to manage the list of artifacts for a modelversion. description: >- @@ -981,6 +954,35 @@ paths: type: string in: path required: true + /api/model_registry/v1alpha1/model_version: + summary: Path used to search for a modelversion. + description: >- + The REST endpoint/path used to search for a `ModelVersion` entity. This path contains a `GET` + operation to perform the find task. + get: + tags: + - ModelRegistryService + responses: + '200': + $ref: '#/components/responses/ModelVersionResponse' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' + operationId: findModelVersion + summary: Get a ModelVersion that matches search parameters. + description: Gets the details of a single instance of a `ModelVersion` that matches search parameters. + parameters: + - + $ref: '#/components/parameters/name' + - + $ref: '#/components/parameters/externalID' + - + $ref: '#/components/parameters/registeredModelID' components: schemas: ArtifactState: @@ -1165,43 +1167,61 @@ components: MetadataValue: oneOf: - - type: object - properties: - int_value: - format: int64 - type: string + $ref: '#/components/schemas/MetadataIntValue' - - type: object - properties: - double_value: - format: double - type: number + $ref: '#/components/schemas/MetadataDoubleValue' - - type: object - properties: - string_value: - type: string + $ref: '#/components/schemas/MetadataStringValue' - - type: object - properties: - struct_value: - description: Base64 encoded bytes for struct value - type: string + $ref: '#/components/schemas/MetadataStructValue' - - type: object - properties: - type: - description: url describing proto value - type: string - proto_value: - description: Base64 encoded bytes for proto value - type: string + $ref: '#/components/schemas/MetadataProtoValue' - - type: object - properties: - bool_value: - type: boolean + $ref: '#/components/schemas/MetadataBoolValue' description: A value in properties. + MetadataIntValue: + description: An integer (int64) property value. + type: object + properties: + int_value: + format: int64 + type: string + MetadataDoubleValue: + description: A double property value. + type: object + properties: + double_value: + format: double + type: number + MetadataStringValue: + description: A string property value. + type: object + properties: + string_value: + type: string + MetadataStructValue: + description: A struct property value. + type: object + properties: + struct_value: + description: Base64 encoded bytes for struct value + type: string + MetadataProtoValue: + description: A proto property value. + type: object + properties: + type: + description: url describing proto value + type: string + proto_value: + description: Base64 encoded bytes for proto value + type: string + MetadataBoolValue: + description: A bool property value. + type: object + properties: + bool_value: + type: boolean BaseResource: allOf: - @@ -1658,6 +1678,16 @@ components: type: string in: query required: false + registeredModelID: + examples: + registeredModelID: + value: '10' + name: registeredModelID + description: ID of the `RegisteredModel` to use for search. + schema: + type: string + in: query + required: false pageSize: examples: pageSize: diff --git a/internal/core/core_test.go b/internal/core/core_test.go index dfb5c3d1..47caec73 100644 --- a/internal/core/core_test.go +++ b/internal/core/core_test.go @@ -44,7 +44,7 @@ func TestCreateRegisteredModel(t *testing.T) { ExternalID: &externalId, CustomProperties: &map[string]openapi.MetadataValue{ "owner": { - MetadataValueOneOf2: &openapi.MetadataValueOneOf2{ + MetadataStringValue: &openapi.MetadataStringValue{ StringValue: &owner, }, }, diff --git a/internal/core/mapper/mlmd_mapper.go b/internal/core/mapper/mlmd_mapper.go index a657d0de..d9572423 100644 --- a/internal/core/mapper/mlmd_mapper.go +++ b/internal/core/mapper/mlmd_mapper.go @@ -51,19 +51,19 @@ func (m *Mapper) MapToProperties(data map[string]openapi.MetadataValue) (map[str switch { // int value - case v.MetadataValueOneOf != nil: - intValue, err := IdToInt64(*v.MetadataValueOneOf.IntValue) + case v.MetadataIntValue != nil: + intValue, err := IdToInt64(*v.MetadataIntValue.IntValue) if err != nil { log.Printf("Skipping mapping for %s:%v", key, v) continue } value.Value = &proto.Value_IntValue{IntValue: *intValue} // double value - case v.MetadataValueOneOf1 != nil: - value.Value = &proto.Value_DoubleValue{DoubleValue: *v.MetadataValueOneOf1.DoubleValue} - // double value - case v.MetadataValueOneOf2 != nil: - value.Value = &proto.Value_StringValue{StringValue: *v.MetadataValueOneOf2.StringValue} + case v.MetadataDoubleValue != nil: + value.Value = &proto.Value_DoubleValue{DoubleValue: *v.MetadataDoubleValue.DoubleValue} + // string value + case v.MetadataStringValue != nil: + value.Value = &proto.Value_StringValue{StringValue: *v.MetadataStringValue.StringValue} default: log.Printf("Type mapping not found for %s:%v", key, v) continue @@ -169,15 +169,15 @@ func (m *Mapper) MapFromProperties(props map[string]*proto.Value) (map[string]op switch typedValue := v.Value.(type) { case *proto.Value_IntValue: - customValue.MetadataValueOneOf = &openapi.MetadataValueOneOf{ + customValue.MetadataIntValue = &openapi.MetadataIntValue{ IntValue: IdToString(typedValue.IntValue), } case *proto.Value_DoubleValue: - customValue.MetadataValueOneOf1 = &openapi.MetadataValueOneOf1{ + customValue.MetadataDoubleValue = &openapi.MetadataDoubleValue{ DoubleValue: &typedValue.DoubleValue, } case *proto.Value_StringValue: - customValue.MetadataValueOneOf2 = &openapi.MetadataValueOneOf2{ + customValue.MetadataStringValue = &openapi.MetadataStringValue{ StringValue: &typedValue.StringValue, } default: diff --git a/internal/model/openapi/.openapi-generator/FILES b/internal/model/openapi/.openapi-generator/FILES index 0efba780..9b78767d 100644 --- a/internal/model/openapi/.openapi-generator/FILES +++ b/internal/model/openapi/.openapi-generator/FILES @@ -20,13 +20,13 @@ model_inference_service.go model_inference_service_create.go model_inference_service_list.go model_inference_service_update.go +model_metadata_bool_value.go +model_metadata_double_value.go +model_metadata_int_value.go +model_metadata_proto_value.go +model_metadata_string_value.go +model_metadata_struct_value.go model_metadata_value.go -model_metadata_value_one_of.go -model_metadata_value_one_of_1.go -model_metadata_value_one_of_2.go -model_metadata_value_one_of_3.go -model_metadata_value_one_of_4.go -model_metadata_value_one_of_5.go model_model_artifact.go model_model_artifact_create.go model_model_artifact_list.go diff --git a/internal/model/openapi/api_model_registry_service.go b/internal/model/openapi/api_model_registry_service.go index f23c4238..cc1129df 100644 --- a/internal/model/openapi/api_model_registry_service.go +++ b/internal/model/openapi/api_model_registry_service.go @@ -1705,10 +1705,11 @@ func (a *ModelRegistryServiceAPIService) FindModelArtifactExecute(r ApiFindModel } type ApiFindModelVersionRequest struct { - ctx context.Context - ApiService *ModelRegistryServiceAPIService - name *string - externalID *string + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string + registeredModelID *string } // Name of entity to search. @@ -1723,6 +1724,12 @@ func (r ApiFindModelVersionRequest) ExternalID(externalID string) ApiFindModelVe return r } +// ID of the `RegisteredModel` to use for search. +func (r ApiFindModelVersionRequest) RegisteredModelID(registeredModelID string) ApiFindModelVersionRequest { + r.registeredModelID = ®isteredModelID + return r +} + func (r ApiFindModelVersionRequest) Execute() (*ModelVersion, *http.Response, error) { return r.ApiService.FindModelVersionExecute(r) } @@ -1770,6 +1777,9 @@ func (a *ModelRegistryServiceAPIService) FindModelVersionExecute(r ApiFindModelV if r.externalID != nil { parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") } + if r.registeredModelID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "registeredModelID", r.registeredModelID, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} diff --git a/internal/model/openapi/model_metadata_value_one_of_5.go b/internal/model/openapi/model_metadata_bool_value.go similarity index 54% rename from internal/model/openapi/model_metadata_value_one_of_5.go rename to internal/model/openapi/model_metadata_bool_value.go index 745320ed..41cb261d 100644 --- a/internal/model/openapi/model_metadata_value_one_of_5.go +++ b/internal/model/openapi/model_metadata_bool_value.go @@ -14,33 +14,33 @@ import ( "encoding/json" ) -// checks if the MetadataValueOneOf5 type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &MetadataValueOneOf5{} +// checks if the MetadataBoolValue type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataBoolValue{} -// MetadataValueOneOf5 struct for MetadataValueOneOf5 -type MetadataValueOneOf5 struct { +// MetadataBoolValue A bool property value. +type MetadataBoolValue struct { BoolValue *bool `json:"bool_value,omitempty"` } -// NewMetadataValueOneOf5 instantiates a new MetadataValueOneOf5 object +// NewMetadataBoolValue instantiates a new MetadataBoolValue object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewMetadataValueOneOf5() *MetadataValueOneOf5 { - this := MetadataValueOneOf5{} +func NewMetadataBoolValue() *MetadataBoolValue { + this := MetadataBoolValue{} return &this } -// NewMetadataValueOneOf5WithDefaults instantiates a new MetadataValueOneOf5 object +// NewMetadataBoolValueWithDefaults instantiates a new MetadataBoolValue object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewMetadataValueOneOf5WithDefaults() *MetadataValueOneOf5 { - this := MetadataValueOneOf5{} +func NewMetadataBoolValueWithDefaults() *MetadataBoolValue { + this := MetadataBoolValue{} return &this } // GetBoolValue returns the BoolValue field value if set, zero value otherwise. -func (o *MetadataValueOneOf5) GetBoolValue() bool { +func (o *MetadataBoolValue) GetBoolValue() bool { if o == nil || IsNil(o.BoolValue) { var ret bool return ret @@ -50,7 +50,7 @@ func (o *MetadataValueOneOf5) GetBoolValue() bool { // GetBoolValueOk returns a tuple with the BoolValue field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *MetadataValueOneOf5) GetBoolValueOk() (*bool, bool) { +func (o *MetadataBoolValue) GetBoolValueOk() (*bool, bool) { if o == nil || IsNil(o.BoolValue) { return nil, false } @@ -58,7 +58,7 @@ func (o *MetadataValueOneOf5) GetBoolValueOk() (*bool, bool) { } // HasBoolValue returns a boolean if a field has been set. -func (o *MetadataValueOneOf5) HasBoolValue() bool { +func (o *MetadataBoolValue) HasBoolValue() bool { if o != nil && !IsNil(o.BoolValue) { return true } @@ -67,11 +67,11 @@ func (o *MetadataValueOneOf5) HasBoolValue() bool { } // SetBoolValue gets a reference to the given bool and assigns it to the BoolValue field. -func (o *MetadataValueOneOf5) SetBoolValue(v bool) { +func (o *MetadataBoolValue) SetBoolValue(v bool) { o.BoolValue = &v } -func (o MetadataValueOneOf5) MarshalJSON() ([]byte, error) { +func (o MetadataBoolValue) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -79,7 +79,7 @@ func (o MetadataValueOneOf5) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o MetadataValueOneOf5) ToMap() (map[string]interface{}, error) { +func (o MetadataBoolValue) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.BoolValue) { toSerialize["bool_value"] = o.BoolValue @@ -87,38 +87,38 @@ func (o MetadataValueOneOf5) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -type NullableMetadataValueOneOf5 struct { - value *MetadataValueOneOf5 +type NullableMetadataBoolValue struct { + value *MetadataBoolValue isSet bool } -func (v NullableMetadataValueOneOf5) Get() *MetadataValueOneOf5 { +func (v NullableMetadataBoolValue) Get() *MetadataBoolValue { return v.value } -func (v *NullableMetadataValueOneOf5) Set(val *MetadataValueOneOf5) { +func (v *NullableMetadataBoolValue) Set(val *MetadataBoolValue) { v.value = val v.isSet = true } -func (v NullableMetadataValueOneOf5) IsSet() bool { +func (v NullableMetadataBoolValue) IsSet() bool { return v.isSet } -func (v *NullableMetadataValueOneOf5) Unset() { +func (v *NullableMetadataBoolValue) Unset() { v.value = nil v.isSet = false } -func NewNullableMetadataValueOneOf5(val *MetadataValueOneOf5) *NullableMetadataValueOneOf5 { - return &NullableMetadataValueOneOf5{value: val, isSet: true} +func NewNullableMetadataBoolValue(val *MetadataBoolValue) *NullableMetadataBoolValue { + return &NullableMetadataBoolValue{value: val, isSet: true} } -func (v NullableMetadataValueOneOf5) MarshalJSON() ([]byte, error) { +func (v NullableMetadataBoolValue) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableMetadataValueOneOf5) UnmarshalJSON(src []byte) error { +func (v *NullableMetadataBoolValue) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/internal/model/openapi/model_metadata_value_one_of_1.go b/internal/model/openapi/model_metadata_double_value.go similarity index 56% rename from internal/model/openapi/model_metadata_value_one_of_1.go rename to internal/model/openapi/model_metadata_double_value.go index 60d232bd..5ab14b9c 100644 --- a/internal/model/openapi/model_metadata_value_one_of_1.go +++ b/internal/model/openapi/model_metadata_double_value.go @@ -14,33 +14,33 @@ import ( "encoding/json" ) -// checks if the MetadataValueOneOf1 type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &MetadataValueOneOf1{} +// checks if the MetadataDoubleValue type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataDoubleValue{} -// MetadataValueOneOf1 struct for MetadataValueOneOf1 -type MetadataValueOneOf1 struct { +// MetadataDoubleValue A double property value. +type MetadataDoubleValue struct { DoubleValue *float64 `json:"double_value,omitempty"` } -// NewMetadataValueOneOf1 instantiates a new MetadataValueOneOf1 object +// NewMetadataDoubleValue instantiates a new MetadataDoubleValue object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewMetadataValueOneOf1() *MetadataValueOneOf1 { - this := MetadataValueOneOf1{} +func NewMetadataDoubleValue() *MetadataDoubleValue { + this := MetadataDoubleValue{} return &this } -// NewMetadataValueOneOf1WithDefaults instantiates a new MetadataValueOneOf1 object +// NewMetadataDoubleValueWithDefaults instantiates a new MetadataDoubleValue object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewMetadataValueOneOf1WithDefaults() *MetadataValueOneOf1 { - this := MetadataValueOneOf1{} +func NewMetadataDoubleValueWithDefaults() *MetadataDoubleValue { + this := MetadataDoubleValue{} return &this } // GetDoubleValue returns the DoubleValue field value if set, zero value otherwise. -func (o *MetadataValueOneOf1) GetDoubleValue() float64 { +func (o *MetadataDoubleValue) GetDoubleValue() float64 { if o == nil || IsNil(o.DoubleValue) { var ret float64 return ret @@ -50,7 +50,7 @@ func (o *MetadataValueOneOf1) GetDoubleValue() float64 { // GetDoubleValueOk returns a tuple with the DoubleValue field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *MetadataValueOneOf1) GetDoubleValueOk() (*float64, bool) { +func (o *MetadataDoubleValue) GetDoubleValueOk() (*float64, bool) { if o == nil || IsNil(o.DoubleValue) { return nil, false } @@ -58,7 +58,7 @@ func (o *MetadataValueOneOf1) GetDoubleValueOk() (*float64, bool) { } // HasDoubleValue returns a boolean if a field has been set. -func (o *MetadataValueOneOf1) HasDoubleValue() bool { +func (o *MetadataDoubleValue) HasDoubleValue() bool { if o != nil && !IsNil(o.DoubleValue) { return true } @@ -67,11 +67,11 @@ func (o *MetadataValueOneOf1) HasDoubleValue() bool { } // SetDoubleValue gets a reference to the given float64 and assigns it to the DoubleValue field. -func (o *MetadataValueOneOf1) SetDoubleValue(v float64) { +func (o *MetadataDoubleValue) SetDoubleValue(v float64) { o.DoubleValue = &v } -func (o MetadataValueOneOf1) MarshalJSON() ([]byte, error) { +func (o MetadataDoubleValue) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -79,7 +79,7 @@ func (o MetadataValueOneOf1) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o MetadataValueOneOf1) ToMap() (map[string]interface{}, error) { +func (o MetadataDoubleValue) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.DoubleValue) { toSerialize["double_value"] = o.DoubleValue @@ -87,38 +87,38 @@ func (o MetadataValueOneOf1) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -type NullableMetadataValueOneOf1 struct { - value *MetadataValueOneOf1 +type NullableMetadataDoubleValue struct { + value *MetadataDoubleValue isSet bool } -func (v NullableMetadataValueOneOf1) Get() *MetadataValueOneOf1 { +func (v NullableMetadataDoubleValue) Get() *MetadataDoubleValue { return v.value } -func (v *NullableMetadataValueOneOf1) Set(val *MetadataValueOneOf1) { +func (v *NullableMetadataDoubleValue) Set(val *MetadataDoubleValue) { v.value = val v.isSet = true } -func (v NullableMetadataValueOneOf1) IsSet() bool { +func (v NullableMetadataDoubleValue) IsSet() bool { return v.isSet } -func (v *NullableMetadataValueOneOf1) Unset() { +func (v *NullableMetadataDoubleValue) Unset() { v.value = nil v.isSet = false } -func NewNullableMetadataValueOneOf1(val *MetadataValueOneOf1) *NullableMetadataValueOneOf1 { - return &NullableMetadataValueOneOf1{value: val, isSet: true} +func NewNullableMetadataDoubleValue(val *MetadataDoubleValue) *NullableMetadataDoubleValue { + return &NullableMetadataDoubleValue{value: val, isSet: true} } -func (v NullableMetadataValueOneOf1) MarshalJSON() ([]byte, error) { +func (v NullableMetadataDoubleValue) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableMetadataValueOneOf1) UnmarshalJSON(src []byte) error { +func (v *NullableMetadataDoubleValue) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/internal/model/openapi/model_metadata_value_one_of.go b/internal/model/openapi/model_metadata_int_value.go similarity index 55% rename from internal/model/openapi/model_metadata_value_one_of.go rename to internal/model/openapi/model_metadata_int_value.go index c9b8615c..367c6cf4 100644 --- a/internal/model/openapi/model_metadata_value_one_of.go +++ b/internal/model/openapi/model_metadata_int_value.go @@ -14,33 +14,33 @@ import ( "encoding/json" ) -// checks if the MetadataValueOneOf type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &MetadataValueOneOf{} +// checks if the MetadataIntValue type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataIntValue{} -// MetadataValueOneOf struct for MetadataValueOneOf -type MetadataValueOneOf struct { +// MetadataIntValue An integer (int64) property value. +type MetadataIntValue struct { IntValue *string `json:"int_value,omitempty"` } -// NewMetadataValueOneOf instantiates a new MetadataValueOneOf object +// NewMetadataIntValue instantiates a new MetadataIntValue object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewMetadataValueOneOf() *MetadataValueOneOf { - this := MetadataValueOneOf{} +func NewMetadataIntValue() *MetadataIntValue { + this := MetadataIntValue{} return &this } -// NewMetadataValueOneOfWithDefaults instantiates a new MetadataValueOneOf object +// NewMetadataIntValueWithDefaults instantiates a new MetadataIntValue object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewMetadataValueOneOfWithDefaults() *MetadataValueOneOf { - this := MetadataValueOneOf{} +func NewMetadataIntValueWithDefaults() *MetadataIntValue { + this := MetadataIntValue{} return &this } // GetIntValue returns the IntValue field value if set, zero value otherwise. -func (o *MetadataValueOneOf) GetIntValue() string { +func (o *MetadataIntValue) GetIntValue() string { if o == nil || IsNil(o.IntValue) { var ret string return ret @@ -50,7 +50,7 @@ func (o *MetadataValueOneOf) GetIntValue() string { // GetIntValueOk returns a tuple with the IntValue field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *MetadataValueOneOf) GetIntValueOk() (*string, bool) { +func (o *MetadataIntValue) GetIntValueOk() (*string, bool) { if o == nil || IsNil(o.IntValue) { return nil, false } @@ -58,7 +58,7 @@ func (o *MetadataValueOneOf) GetIntValueOk() (*string, bool) { } // HasIntValue returns a boolean if a field has been set. -func (o *MetadataValueOneOf) HasIntValue() bool { +func (o *MetadataIntValue) HasIntValue() bool { if o != nil && !IsNil(o.IntValue) { return true } @@ -67,11 +67,11 @@ func (o *MetadataValueOneOf) HasIntValue() bool { } // SetIntValue gets a reference to the given string and assigns it to the IntValue field. -func (o *MetadataValueOneOf) SetIntValue(v string) { +func (o *MetadataIntValue) SetIntValue(v string) { o.IntValue = &v } -func (o MetadataValueOneOf) MarshalJSON() ([]byte, error) { +func (o MetadataIntValue) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -79,7 +79,7 @@ func (o MetadataValueOneOf) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o MetadataValueOneOf) ToMap() (map[string]interface{}, error) { +func (o MetadataIntValue) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.IntValue) { toSerialize["int_value"] = o.IntValue @@ -87,38 +87,38 @@ func (o MetadataValueOneOf) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -type NullableMetadataValueOneOf struct { - value *MetadataValueOneOf +type NullableMetadataIntValue struct { + value *MetadataIntValue isSet bool } -func (v NullableMetadataValueOneOf) Get() *MetadataValueOneOf { +func (v NullableMetadataIntValue) Get() *MetadataIntValue { return v.value } -func (v *NullableMetadataValueOneOf) Set(val *MetadataValueOneOf) { +func (v *NullableMetadataIntValue) Set(val *MetadataIntValue) { v.value = val v.isSet = true } -func (v NullableMetadataValueOneOf) IsSet() bool { +func (v NullableMetadataIntValue) IsSet() bool { return v.isSet } -func (v *NullableMetadataValueOneOf) Unset() { +func (v *NullableMetadataIntValue) Unset() { v.value = nil v.isSet = false } -func NewNullableMetadataValueOneOf(val *MetadataValueOneOf) *NullableMetadataValueOneOf { - return &NullableMetadataValueOneOf{value: val, isSet: true} +func NewNullableMetadataIntValue(val *MetadataIntValue) *NullableMetadataIntValue { + return &NullableMetadataIntValue{value: val, isSet: true} } -func (v NullableMetadataValueOneOf) MarshalJSON() ([]byte, error) { +func (v NullableMetadataIntValue) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableMetadataValueOneOf) UnmarshalJSON(src []byte) error { +func (v *NullableMetadataIntValue) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/internal/model/openapi/model_metadata_value_one_of_4.go b/internal/model/openapi/model_metadata_proto_value.go similarity index 59% rename from internal/model/openapi/model_metadata_value_one_of_4.go rename to internal/model/openapi/model_metadata_proto_value.go index 622f9810..1c29ecd2 100644 --- a/internal/model/openapi/model_metadata_value_one_of_4.go +++ b/internal/model/openapi/model_metadata_proto_value.go @@ -14,36 +14,36 @@ import ( "encoding/json" ) -// checks if the MetadataValueOneOf4 type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &MetadataValueOneOf4{} +// checks if the MetadataProtoValue type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataProtoValue{} -// MetadataValueOneOf4 struct for MetadataValueOneOf4 -type MetadataValueOneOf4 struct { +// MetadataProtoValue A proto property value. +type MetadataProtoValue struct { // url describing proto value Type *string `json:"type,omitempty"` // Base64 encoded bytes for proto value ProtoValue *string `json:"proto_value,omitempty"` } -// NewMetadataValueOneOf4 instantiates a new MetadataValueOneOf4 object +// NewMetadataProtoValue instantiates a new MetadataProtoValue object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewMetadataValueOneOf4() *MetadataValueOneOf4 { - this := MetadataValueOneOf4{} +func NewMetadataProtoValue() *MetadataProtoValue { + this := MetadataProtoValue{} return &this } -// NewMetadataValueOneOf4WithDefaults instantiates a new MetadataValueOneOf4 object +// NewMetadataProtoValueWithDefaults instantiates a new MetadataProtoValue object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewMetadataValueOneOf4WithDefaults() *MetadataValueOneOf4 { - this := MetadataValueOneOf4{} +func NewMetadataProtoValueWithDefaults() *MetadataProtoValue { + this := MetadataProtoValue{} return &this } // GetType returns the Type field value if set, zero value otherwise. -func (o *MetadataValueOneOf4) GetType() string { +func (o *MetadataProtoValue) GetType() string { if o == nil || IsNil(o.Type) { var ret string return ret @@ -53,7 +53,7 @@ func (o *MetadataValueOneOf4) GetType() string { // GetTypeOk returns a tuple with the Type field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *MetadataValueOneOf4) GetTypeOk() (*string, bool) { +func (o *MetadataProtoValue) GetTypeOk() (*string, bool) { if o == nil || IsNil(o.Type) { return nil, false } @@ -61,7 +61,7 @@ func (o *MetadataValueOneOf4) GetTypeOk() (*string, bool) { } // HasType returns a boolean if a field has been set. -func (o *MetadataValueOneOf4) HasType() bool { +func (o *MetadataProtoValue) HasType() bool { if o != nil && !IsNil(o.Type) { return true } @@ -70,12 +70,12 @@ func (o *MetadataValueOneOf4) HasType() bool { } // SetType gets a reference to the given string and assigns it to the Type field. -func (o *MetadataValueOneOf4) SetType(v string) { +func (o *MetadataProtoValue) SetType(v string) { o.Type = &v } // GetProtoValue returns the ProtoValue field value if set, zero value otherwise. -func (o *MetadataValueOneOf4) GetProtoValue() string { +func (o *MetadataProtoValue) GetProtoValue() string { if o == nil || IsNil(o.ProtoValue) { var ret string return ret @@ -85,7 +85,7 @@ func (o *MetadataValueOneOf4) GetProtoValue() string { // GetProtoValueOk returns a tuple with the ProtoValue field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *MetadataValueOneOf4) GetProtoValueOk() (*string, bool) { +func (o *MetadataProtoValue) GetProtoValueOk() (*string, bool) { if o == nil || IsNil(o.ProtoValue) { return nil, false } @@ -93,7 +93,7 @@ func (o *MetadataValueOneOf4) GetProtoValueOk() (*string, bool) { } // HasProtoValue returns a boolean if a field has been set. -func (o *MetadataValueOneOf4) HasProtoValue() bool { +func (o *MetadataProtoValue) HasProtoValue() bool { if o != nil && !IsNil(o.ProtoValue) { return true } @@ -102,11 +102,11 @@ func (o *MetadataValueOneOf4) HasProtoValue() bool { } // SetProtoValue gets a reference to the given string and assigns it to the ProtoValue field. -func (o *MetadataValueOneOf4) SetProtoValue(v string) { +func (o *MetadataProtoValue) SetProtoValue(v string) { o.ProtoValue = &v } -func (o MetadataValueOneOf4) MarshalJSON() ([]byte, error) { +func (o MetadataProtoValue) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -114,7 +114,7 @@ func (o MetadataValueOneOf4) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o MetadataValueOneOf4) ToMap() (map[string]interface{}, error) { +func (o MetadataProtoValue) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.Type) { toSerialize["type"] = o.Type @@ -125,38 +125,38 @@ func (o MetadataValueOneOf4) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -type NullableMetadataValueOneOf4 struct { - value *MetadataValueOneOf4 +type NullableMetadataProtoValue struct { + value *MetadataProtoValue isSet bool } -func (v NullableMetadataValueOneOf4) Get() *MetadataValueOneOf4 { +func (v NullableMetadataProtoValue) Get() *MetadataProtoValue { return v.value } -func (v *NullableMetadataValueOneOf4) Set(val *MetadataValueOneOf4) { +func (v *NullableMetadataProtoValue) Set(val *MetadataProtoValue) { v.value = val v.isSet = true } -func (v NullableMetadataValueOneOf4) IsSet() bool { +func (v NullableMetadataProtoValue) IsSet() bool { return v.isSet } -func (v *NullableMetadataValueOneOf4) Unset() { +func (v *NullableMetadataProtoValue) Unset() { v.value = nil v.isSet = false } -func NewNullableMetadataValueOneOf4(val *MetadataValueOneOf4) *NullableMetadataValueOneOf4 { - return &NullableMetadataValueOneOf4{value: val, isSet: true} +func NewNullableMetadataProtoValue(val *MetadataProtoValue) *NullableMetadataProtoValue { + return &NullableMetadataProtoValue{value: val, isSet: true} } -func (v NullableMetadataValueOneOf4) MarshalJSON() ([]byte, error) { +func (v NullableMetadataProtoValue) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableMetadataValueOneOf4) UnmarshalJSON(src []byte) error { +func (v *NullableMetadataProtoValue) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/internal/model/openapi/model_metadata_value_one_of_2.go b/internal/model/openapi/model_metadata_string_value.go similarity index 56% rename from internal/model/openapi/model_metadata_value_one_of_2.go rename to internal/model/openapi/model_metadata_string_value.go index 51a96b9f..bf40139a 100644 --- a/internal/model/openapi/model_metadata_value_one_of_2.go +++ b/internal/model/openapi/model_metadata_string_value.go @@ -14,33 +14,33 @@ import ( "encoding/json" ) -// checks if the MetadataValueOneOf2 type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &MetadataValueOneOf2{} +// checks if the MetadataStringValue type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataStringValue{} -// MetadataValueOneOf2 struct for MetadataValueOneOf2 -type MetadataValueOneOf2 struct { +// MetadataStringValue A string property value. +type MetadataStringValue struct { StringValue *string `json:"string_value,omitempty"` } -// NewMetadataValueOneOf2 instantiates a new MetadataValueOneOf2 object +// NewMetadataStringValue instantiates a new MetadataStringValue object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewMetadataValueOneOf2() *MetadataValueOneOf2 { - this := MetadataValueOneOf2{} +func NewMetadataStringValue() *MetadataStringValue { + this := MetadataStringValue{} return &this } -// NewMetadataValueOneOf2WithDefaults instantiates a new MetadataValueOneOf2 object +// NewMetadataStringValueWithDefaults instantiates a new MetadataStringValue object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewMetadataValueOneOf2WithDefaults() *MetadataValueOneOf2 { - this := MetadataValueOneOf2{} +func NewMetadataStringValueWithDefaults() *MetadataStringValue { + this := MetadataStringValue{} return &this } // GetStringValue returns the StringValue field value if set, zero value otherwise. -func (o *MetadataValueOneOf2) GetStringValue() string { +func (o *MetadataStringValue) GetStringValue() string { if o == nil || IsNil(o.StringValue) { var ret string return ret @@ -50,7 +50,7 @@ func (o *MetadataValueOneOf2) GetStringValue() string { // GetStringValueOk returns a tuple with the StringValue field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *MetadataValueOneOf2) GetStringValueOk() (*string, bool) { +func (o *MetadataStringValue) GetStringValueOk() (*string, bool) { if o == nil || IsNil(o.StringValue) { return nil, false } @@ -58,7 +58,7 @@ func (o *MetadataValueOneOf2) GetStringValueOk() (*string, bool) { } // HasStringValue returns a boolean if a field has been set. -func (o *MetadataValueOneOf2) HasStringValue() bool { +func (o *MetadataStringValue) HasStringValue() bool { if o != nil && !IsNil(o.StringValue) { return true } @@ -67,11 +67,11 @@ func (o *MetadataValueOneOf2) HasStringValue() bool { } // SetStringValue gets a reference to the given string and assigns it to the StringValue field. -func (o *MetadataValueOneOf2) SetStringValue(v string) { +func (o *MetadataStringValue) SetStringValue(v string) { o.StringValue = &v } -func (o MetadataValueOneOf2) MarshalJSON() ([]byte, error) { +func (o MetadataStringValue) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -79,7 +79,7 @@ func (o MetadataValueOneOf2) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o MetadataValueOneOf2) ToMap() (map[string]interface{}, error) { +func (o MetadataStringValue) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.StringValue) { toSerialize["string_value"] = o.StringValue @@ -87,38 +87,38 @@ func (o MetadataValueOneOf2) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -type NullableMetadataValueOneOf2 struct { - value *MetadataValueOneOf2 +type NullableMetadataStringValue struct { + value *MetadataStringValue isSet bool } -func (v NullableMetadataValueOneOf2) Get() *MetadataValueOneOf2 { +func (v NullableMetadataStringValue) Get() *MetadataStringValue { return v.value } -func (v *NullableMetadataValueOneOf2) Set(val *MetadataValueOneOf2) { +func (v *NullableMetadataStringValue) Set(val *MetadataStringValue) { v.value = val v.isSet = true } -func (v NullableMetadataValueOneOf2) IsSet() bool { +func (v NullableMetadataStringValue) IsSet() bool { return v.isSet } -func (v *NullableMetadataValueOneOf2) Unset() { +func (v *NullableMetadataStringValue) Unset() { v.value = nil v.isSet = false } -func NewNullableMetadataValueOneOf2(val *MetadataValueOneOf2) *NullableMetadataValueOneOf2 { - return &NullableMetadataValueOneOf2{value: val, isSet: true} +func NewNullableMetadataStringValue(val *MetadataStringValue) *NullableMetadataStringValue { + return &NullableMetadataStringValue{value: val, isSet: true} } -func (v NullableMetadataValueOneOf2) MarshalJSON() ([]byte, error) { +func (v NullableMetadataStringValue) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableMetadataValueOneOf2) UnmarshalJSON(src []byte) error { +func (v *NullableMetadataStringValue) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/internal/model/openapi/model_metadata_value_one_of_3.go b/internal/model/openapi/model_metadata_struct_value.go similarity index 57% rename from internal/model/openapi/model_metadata_value_one_of_3.go rename to internal/model/openapi/model_metadata_struct_value.go index c637edd9..fc4255ca 100644 --- a/internal/model/openapi/model_metadata_value_one_of_3.go +++ b/internal/model/openapi/model_metadata_struct_value.go @@ -14,34 +14,34 @@ import ( "encoding/json" ) -// checks if the MetadataValueOneOf3 type satisfies the MappedNullable interface at compile time -var _ MappedNullable = &MetadataValueOneOf3{} +// checks if the MetadataStructValue type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &MetadataStructValue{} -// MetadataValueOneOf3 struct for MetadataValueOneOf3 -type MetadataValueOneOf3 struct { +// MetadataStructValue A struct property value. +type MetadataStructValue struct { // Base64 encoded bytes for struct value StructValue *string `json:"struct_value,omitempty"` } -// NewMetadataValueOneOf3 instantiates a new MetadataValueOneOf3 object +// NewMetadataStructValue instantiates a new MetadataStructValue object // This constructor will assign default values to properties that have it defined, // and makes sure properties required by API are set, but the set of arguments // will change when the set of required properties is changed -func NewMetadataValueOneOf3() *MetadataValueOneOf3 { - this := MetadataValueOneOf3{} +func NewMetadataStructValue() *MetadataStructValue { + this := MetadataStructValue{} return &this } -// NewMetadataValueOneOf3WithDefaults instantiates a new MetadataValueOneOf3 object +// NewMetadataStructValueWithDefaults instantiates a new MetadataStructValue object // This constructor will only assign default values to properties that have it defined, // but it doesn't guarantee that properties required by API are set -func NewMetadataValueOneOf3WithDefaults() *MetadataValueOneOf3 { - this := MetadataValueOneOf3{} +func NewMetadataStructValueWithDefaults() *MetadataStructValue { + this := MetadataStructValue{} return &this } // GetStructValue returns the StructValue field value if set, zero value otherwise. -func (o *MetadataValueOneOf3) GetStructValue() string { +func (o *MetadataStructValue) GetStructValue() string { if o == nil || IsNil(o.StructValue) { var ret string return ret @@ -51,7 +51,7 @@ func (o *MetadataValueOneOf3) GetStructValue() string { // GetStructValueOk returns a tuple with the StructValue field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *MetadataValueOneOf3) GetStructValueOk() (*string, bool) { +func (o *MetadataStructValue) GetStructValueOk() (*string, bool) { if o == nil || IsNil(o.StructValue) { return nil, false } @@ -59,7 +59,7 @@ func (o *MetadataValueOneOf3) GetStructValueOk() (*string, bool) { } // HasStructValue returns a boolean if a field has been set. -func (o *MetadataValueOneOf3) HasStructValue() bool { +func (o *MetadataStructValue) HasStructValue() bool { if o != nil && !IsNil(o.StructValue) { return true } @@ -68,11 +68,11 @@ func (o *MetadataValueOneOf3) HasStructValue() bool { } // SetStructValue gets a reference to the given string and assigns it to the StructValue field. -func (o *MetadataValueOneOf3) SetStructValue(v string) { +func (o *MetadataStructValue) SetStructValue(v string) { o.StructValue = &v } -func (o MetadataValueOneOf3) MarshalJSON() ([]byte, error) { +func (o MetadataStructValue) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { return []byte{}, err @@ -80,7 +80,7 @@ func (o MetadataValueOneOf3) MarshalJSON() ([]byte, error) { return json.Marshal(toSerialize) } -func (o MetadataValueOneOf3) ToMap() (map[string]interface{}, error) { +func (o MetadataStructValue) ToMap() (map[string]interface{}, error) { toSerialize := map[string]interface{}{} if !IsNil(o.StructValue) { toSerialize["struct_value"] = o.StructValue @@ -88,38 +88,38 @@ func (o MetadataValueOneOf3) ToMap() (map[string]interface{}, error) { return toSerialize, nil } -type NullableMetadataValueOneOf3 struct { - value *MetadataValueOneOf3 +type NullableMetadataStructValue struct { + value *MetadataStructValue isSet bool } -func (v NullableMetadataValueOneOf3) Get() *MetadataValueOneOf3 { +func (v NullableMetadataStructValue) Get() *MetadataStructValue { return v.value } -func (v *NullableMetadataValueOneOf3) Set(val *MetadataValueOneOf3) { +func (v *NullableMetadataStructValue) Set(val *MetadataStructValue) { v.value = val v.isSet = true } -func (v NullableMetadataValueOneOf3) IsSet() bool { +func (v NullableMetadataStructValue) IsSet() bool { return v.isSet } -func (v *NullableMetadataValueOneOf3) Unset() { +func (v *NullableMetadataStructValue) Unset() { v.value = nil v.isSet = false } -func NewNullableMetadataValueOneOf3(val *MetadataValueOneOf3) *NullableMetadataValueOneOf3 { - return &NullableMetadataValueOneOf3{value: val, isSet: true} +func NewNullableMetadataStructValue(val *MetadataStructValue) *NullableMetadataStructValue { + return &NullableMetadataStructValue{value: val, isSet: true} } -func (v NullableMetadataValueOneOf3) MarshalJSON() ([]byte, error) { +func (v NullableMetadataStructValue) MarshalJSON() ([]byte, error) { return json.Marshal(v.value) } -func (v *NullableMetadataValueOneOf3) UnmarshalJSON(src []byte) error { +func (v *NullableMetadataStructValue) UnmarshalJSON(src []byte) error { v.isSet = true return json.Unmarshal(src, &v.value) } diff --git a/internal/model/openapi/model_metadata_value.go b/internal/model/openapi/model_metadata_value.go index e2687469..1ae1e9a0 100644 --- a/internal/model/openapi/model_metadata_value.go +++ b/internal/model/openapi/model_metadata_value.go @@ -17,53 +17,53 @@ import ( // MetadataValue - A value in properties. type MetadataValue struct { - MetadataValueOneOf *MetadataValueOneOf - MetadataValueOneOf1 *MetadataValueOneOf1 - MetadataValueOneOf2 *MetadataValueOneOf2 - MetadataValueOneOf3 *MetadataValueOneOf3 - MetadataValueOneOf4 *MetadataValueOneOf4 - MetadataValueOneOf5 *MetadataValueOneOf5 + MetadataBoolValue *MetadataBoolValue + MetadataDoubleValue *MetadataDoubleValue + MetadataIntValue *MetadataIntValue + MetadataProtoValue *MetadataProtoValue + MetadataStringValue *MetadataStringValue + MetadataStructValue *MetadataStructValue } -// MetadataValueOneOfAsMetadataValue is a convenience function that returns MetadataValueOneOf wrapped in MetadataValue -func MetadataValueOneOfAsMetadataValue(v *MetadataValueOneOf) MetadataValue { +// MetadataBoolValueAsMetadataValue is a convenience function that returns MetadataBoolValue wrapped in MetadataValue +func MetadataBoolValueAsMetadataValue(v *MetadataBoolValue) MetadataValue { return MetadataValue{ - MetadataValueOneOf: v, + MetadataBoolValue: v, } } -// MetadataValueOneOf1AsMetadataValue is a convenience function that returns MetadataValueOneOf1 wrapped in MetadataValue -func MetadataValueOneOf1AsMetadataValue(v *MetadataValueOneOf1) MetadataValue { +// MetadataDoubleValueAsMetadataValue is a convenience function that returns MetadataDoubleValue wrapped in MetadataValue +func MetadataDoubleValueAsMetadataValue(v *MetadataDoubleValue) MetadataValue { return MetadataValue{ - MetadataValueOneOf1: v, + MetadataDoubleValue: v, } } -// MetadataValueOneOf2AsMetadataValue is a convenience function that returns MetadataValueOneOf2 wrapped in MetadataValue -func MetadataValueOneOf2AsMetadataValue(v *MetadataValueOneOf2) MetadataValue { +// MetadataIntValueAsMetadataValue is a convenience function that returns MetadataIntValue wrapped in MetadataValue +func MetadataIntValueAsMetadataValue(v *MetadataIntValue) MetadataValue { return MetadataValue{ - MetadataValueOneOf2: v, + MetadataIntValue: v, } } -// MetadataValueOneOf3AsMetadataValue is a convenience function that returns MetadataValueOneOf3 wrapped in MetadataValue -func MetadataValueOneOf3AsMetadataValue(v *MetadataValueOneOf3) MetadataValue { +// MetadataProtoValueAsMetadataValue is a convenience function that returns MetadataProtoValue wrapped in MetadataValue +func MetadataProtoValueAsMetadataValue(v *MetadataProtoValue) MetadataValue { return MetadataValue{ - MetadataValueOneOf3: v, + MetadataProtoValue: v, } } -// MetadataValueOneOf4AsMetadataValue is a convenience function that returns MetadataValueOneOf4 wrapped in MetadataValue -func MetadataValueOneOf4AsMetadataValue(v *MetadataValueOneOf4) MetadataValue { +// MetadataStringValueAsMetadataValue is a convenience function that returns MetadataStringValue wrapped in MetadataValue +func MetadataStringValueAsMetadataValue(v *MetadataStringValue) MetadataValue { return MetadataValue{ - MetadataValueOneOf4: v, + MetadataStringValue: v, } } -// MetadataValueOneOf5AsMetadataValue is a convenience function that returns MetadataValueOneOf5 wrapped in MetadataValue -func MetadataValueOneOf5AsMetadataValue(v *MetadataValueOneOf5) MetadataValue { +// MetadataStructValueAsMetadataValue is a convenience function that returns MetadataStructValue wrapped in MetadataValue +func MetadataStructValueAsMetadataValue(v *MetadataStructValue) MetadataValue { return MetadataValue{ - MetadataValueOneOf5: v, + MetadataStructValue: v, } } @@ -71,92 +71,92 @@ func MetadataValueOneOf5AsMetadataValue(v *MetadataValueOneOf5) MetadataValue { func (dst *MetadataValue) UnmarshalJSON(data []byte) error { var err error match := 0 - // try to unmarshal data into MetadataValueOneOf - err = json.Unmarshal(data, &dst.MetadataValueOneOf) + // try to unmarshal data into MetadataBoolValue + err = json.Unmarshal(data, &dst.MetadataBoolValue) if err == nil { - jsonMetadataValueOneOf, _ := json.Marshal(dst.MetadataValueOneOf) - if string(jsonMetadataValueOneOf) == "{}" { // empty struct - dst.MetadataValueOneOf = nil + jsonMetadataBoolValue, _ := json.Marshal(dst.MetadataBoolValue) + if string(jsonMetadataBoolValue) == "{}" { // empty struct + dst.MetadataBoolValue = nil } else { match++ } } else { - dst.MetadataValueOneOf = nil + dst.MetadataBoolValue = nil } - // try to unmarshal data into MetadataValueOneOf1 - err = json.Unmarshal(data, &dst.MetadataValueOneOf1) + // try to unmarshal data into MetadataDoubleValue + err = json.Unmarshal(data, &dst.MetadataDoubleValue) if err == nil { - jsonMetadataValueOneOf1, _ := json.Marshal(dst.MetadataValueOneOf1) - if string(jsonMetadataValueOneOf1) == "{}" { // empty struct - dst.MetadataValueOneOf1 = nil + jsonMetadataDoubleValue, _ := json.Marshal(dst.MetadataDoubleValue) + if string(jsonMetadataDoubleValue) == "{}" { // empty struct + dst.MetadataDoubleValue = nil } else { match++ } } else { - dst.MetadataValueOneOf1 = nil + dst.MetadataDoubleValue = nil } - // try to unmarshal data into MetadataValueOneOf2 - err = json.Unmarshal(data, &dst.MetadataValueOneOf2) + // try to unmarshal data into MetadataIntValue + err = json.Unmarshal(data, &dst.MetadataIntValue) if err == nil { - jsonMetadataValueOneOf2, _ := json.Marshal(dst.MetadataValueOneOf2) - if string(jsonMetadataValueOneOf2) == "{}" { // empty struct - dst.MetadataValueOneOf2 = nil + jsonMetadataIntValue, _ := json.Marshal(dst.MetadataIntValue) + if string(jsonMetadataIntValue) == "{}" { // empty struct + dst.MetadataIntValue = nil } else { match++ } } else { - dst.MetadataValueOneOf2 = nil + dst.MetadataIntValue = nil } - // try to unmarshal data into MetadataValueOneOf3 - err = json.Unmarshal(data, &dst.MetadataValueOneOf3) + // try to unmarshal data into MetadataProtoValue + err = json.Unmarshal(data, &dst.MetadataProtoValue) if err == nil { - jsonMetadataValueOneOf3, _ := json.Marshal(dst.MetadataValueOneOf3) - if string(jsonMetadataValueOneOf3) == "{}" { // empty struct - dst.MetadataValueOneOf3 = nil + jsonMetadataProtoValue, _ := json.Marshal(dst.MetadataProtoValue) + if string(jsonMetadataProtoValue) == "{}" { // empty struct + dst.MetadataProtoValue = nil } else { match++ } } else { - dst.MetadataValueOneOf3 = nil + dst.MetadataProtoValue = nil } - // try to unmarshal data into MetadataValueOneOf4 - err = json.Unmarshal(data, &dst.MetadataValueOneOf4) + // try to unmarshal data into MetadataStringValue + err = json.Unmarshal(data, &dst.MetadataStringValue) if err == nil { - jsonMetadataValueOneOf4, _ := json.Marshal(dst.MetadataValueOneOf4) - if string(jsonMetadataValueOneOf4) == "{}" { // empty struct - dst.MetadataValueOneOf4 = nil + jsonMetadataStringValue, _ := json.Marshal(dst.MetadataStringValue) + if string(jsonMetadataStringValue) == "{}" { // empty struct + dst.MetadataStringValue = nil } else { match++ } } else { - dst.MetadataValueOneOf4 = nil + dst.MetadataStringValue = nil } - // try to unmarshal data into MetadataValueOneOf5 - err = json.Unmarshal(data, &dst.MetadataValueOneOf5) + // try to unmarshal data into MetadataStructValue + err = json.Unmarshal(data, &dst.MetadataStructValue) if err == nil { - jsonMetadataValueOneOf5, _ := json.Marshal(dst.MetadataValueOneOf5) - if string(jsonMetadataValueOneOf5) == "{}" { // empty struct - dst.MetadataValueOneOf5 = nil + jsonMetadataStructValue, _ := json.Marshal(dst.MetadataStructValue) + if string(jsonMetadataStructValue) == "{}" { // empty struct + dst.MetadataStructValue = nil } else { match++ } } else { - dst.MetadataValueOneOf5 = nil + dst.MetadataStructValue = nil } if match > 1 { // more than 1 match // reset to nil - dst.MetadataValueOneOf = nil - dst.MetadataValueOneOf1 = nil - dst.MetadataValueOneOf2 = nil - dst.MetadataValueOneOf3 = nil - dst.MetadataValueOneOf4 = nil - dst.MetadataValueOneOf5 = nil + dst.MetadataBoolValue = nil + dst.MetadataDoubleValue = nil + dst.MetadataIntValue = nil + dst.MetadataProtoValue = nil + dst.MetadataStringValue = nil + dst.MetadataStructValue = nil return fmt.Errorf("data matches more than one schema in oneOf(MetadataValue)") } else if match == 1 { @@ -168,28 +168,28 @@ func (dst *MetadataValue) UnmarshalJSON(data []byte) error { // Marshal data from the first non-nil pointers in the struct to JSON func (src MetadataValue) MarshalJSON() ([]byte, error) { - if src.MetadataValueOneOf != nil { - return json.Marshal(&src.MetadataValueOneOf) + if src.MetadataBoolValue != nil { + return json.Marshal(&src.MetadataBoolValue) } - if src.MetadataValueOneOf1 != nil { - return json.Marshal(&src.MetadataValueOneOf1) + if src.MetadataDoubleValue != nil { + return json.Marshal(&src.MetadataDoubleValue) } - if src.MetadataValueOneOf2 != nil { - return json.Marshal(&src.MetadataValueOneOf2) + if src.MetadataIntValue != nil { + return json.Marshal(&src.MetadataIntValue) } - if src.MetadataValueOneOf3 != nil { - return json.Marshal(&src.MetadataValueOneOf3) + if src.MetadataProtoValue != nil { + return json.Marshal(&src.MetadataProtoValue) } - if src.MetadataValueOneOf4 != nil { - return json.Marshal(&src.MetadataValueOneOf4) + if src.MetadataStringValue != nil { + return json.Marshal(&src.MetadataStringValue) } - if src.MetadataValueOneOf5 != nil { - return json.Marshal(&src.MetadataValueOneOf5) + if src.MetadataStructValue != nil { + return json.Marshal(&src.MetadataStructValue) } return nil, nil // no data in oneOf schemas @@ -200,28 +200,28 @@ func (obj *MetadataValue) GetActualInstance() interface{} { if obj == nil { return nil } - if obj.MetadataValueOneOf != nil { - return obj.MetadataValueOneOf + if obj.MetadataBoolValue != nil { + return obj.MetadataBoolValue } - if obj.MetadataValueOneOf1 != nil { - return obj.MetadataValueOneOf1 + if obj.MetadataDoubleValue != nil { + return obj.MetadataDoubleValue } - if obj.MetadataValueOneOf2 != nil { - return obj.MetadataValueOneOf2 + if obj.MetadataIntValue != nil { + return obj.MetadataIntValue } - if obj.MetadataValueOneOf3 != nil { - return obj.MetadataValueOneOf3 + if obj.MetadataProtoValue != nil { + return obj.MetadataProtoValue } - if obj.MetadataValueOneOf4 != nil { - return obj.MetadataValueOneOf4 + if obj.MetadataStringValue != nil { + return obj.MetadataStringValue } - if obj.MetadataValueOneOf5 != nil { - return obj.MetadataValueOneOf5 + if obj.MetadataStructValue != nil { + return obj.MetadataStructValue } // all schemas are nil diff --git a/internal/server/openapi/.openapi-generator/FILES b/internal/server/openapi/.openapi-generator/FILES index b42c7f76..0e1bc12c 100644 --- a/internal/server/openapi/.openapi-generator/FILES +++ b/internal/server/openapi/.openapi-generator/FILES @@ -4,52 +4,4 @@ error.go helpers.go impl.go logger.go -model_artifact.go -model_artifact_list.go -model_artifact_state.go -model_base_artifact.go -model_base_artifact_create.go -model_base_artifact_update.go -model_base_execution.go -model_base_execution_create.go -model_base_execution_update.go -model_base_resource.go -model_base_resource_create.go -model_base_resource_list.go -model_base_resource_update.go -model_error.go -model_execution_state.go -model_inference_service.go -model_inference_service_create.go -model_inference_service_list.go -model_inference_service_update.go -model_metadata_value.go -model_metadata_value_one_of.go -model_metadata_value_one_of_1.go -model_metadata_value_one_of_2.go -model_metadata_value_one_of_3.go -model_metadata_value_one_of_4.go -model_metadata_value_one_of_5.go -model_model_artifact.go -model_model_artifact_create.go -model_model_artifact_list.go -model_model_artifact_update.go -model_model_version.go -model_model_version_create.go -model_model_version_list.go -model_model_version_update.go -model_order_by_field.go -model_registered_model.go -model_registered_model_create.go -model_registered_model_list.go -model_registered_model_update.go -model_serve_model.go -model_serve_model_create.go -model_serve_model_list.go -model_serve_model_update.go -model_serving_environment.go -model_serving_environment_create.go -model_serving_environment_list.go -model_serving_environment_update.go -model_sort_order.go routers.go diff --git a/internal/server/openapi/api.go b/internal/server/openapi/api.go index 51c7ad32..899f3cc7 100644 --- a/internal/server/openapi/api.go +++ b/internal/server/openapi/api.go @@ -72,7 +72,7 @@ type ModelRegistryServiceAPIServicer interface { CreateServingEnvironment(context.Context, model.ServingEnvironmentCreate) (ImplResponse, error) FindInferenceService(context.Context, string, string) (ImplResponse, error) FindModelArtifact(context.Context, string, string) (ImplResponse, error) - FindModelVersion(context.Context, string, string) (ImplResponse, error) + FindModelVersion(context.Context, string, string, string) (ImplResponse, error) FindRegisteredModel(context.Context, string, string) (ImplResponse, error) FindServingEnvironment(context.Context, string, string) (ImplResponse, error) GetEnvironmentInferenceServices(context.Context, string, string, string, string, model.OrderByField, model.SortOrder, string) (ImplResponse, error) diff --git a/internal/server/openapi/api_model_registry_service.go b/internal/server/openapi/api_model_registry_service.go index 1e223952..4454a487 100644 --- a/internal/server/openapi/api_model_registry_service.go +++ b/internal/server/openapi/api_model_registry_service.go @@ -11,11 +11,11 @@ package openapi import ( "encoding/json" + model "github.com/opendatahub-io/model-registry/internal/model/openapi" "net/http" "strings" "github.com/go-chi/chi/v5" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" ) // ModelRegistryServiceAPIController binds http requests to an api service and writes the service results to the http response @@ -511,7 +511,8 @@ func (c *ModelRegistryServiceAPIController) FindModelVersion(w http.ResponseWrit query := r.URL.Query() nameParam := query.Get("name") externalIDParam := query.Get("externalID") - result, err := c.service.FindModelVersion(r.Context(), nameParam, externalIDParam) + registeredModelIDParam := query.Get("registeredModelID") + result, err := c.service.FindModelVersion(r.Context(), nameParam, externalIDParam, registeredModelIDParam) // If an error occurred, encode the error with the status code if err != nil { c.errorHandler(w, r, err, &result) diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index e9cd5509..bd8c4906 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -269,7 +269,7 @@ func (s *ModelRegistryServiceAPIService) FindModelArtifact(ctx context.Context, } // FindModelVersion - Get a ModelVersion that matches search parameters. -func (s *ModelRegistryServiceAPIService) FindModelVersion(ctx context.Context, name string, externalID string) (ImplResponse, error) { +func (s *ModelRegistryServiceAPIService) FindModelVersion(ctx context.Context, name string, externalID string, registeredModelID string) (ImplResponse, error) { // TODO - update FindModelVersion with the required logic for this service method. // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go index 6b8dfc89..481efdb6 100644 --- a/internal/server/openapi/type_asserts.go +++ b/internal/server/openapi/type_asserts.go @@ -58,7 +58,6 @@ func AssertArtifactListConstraints(obj model.ArtifactList) error { return nil } - // AssertArtifactStateRequired checks if the required fields are not zero-ed func AssertArtifactStateRequired(obj model.ArtifactState) error { return nil @@ -69,7 +68,6 @@ func AssertArtifactStateConstraints(obj model.ArtifactState) error { return nil } - // AssertBaseArtifactCreateRequired checks if the required fields are not zero-ed func AssertBaseArtifactCreateRequired(obj model.BaseArtifactCreate) error { return nil @@ -80,7 +78,6 @@ func AssertBaseArtifactCreateConstraints(obj model.BaseArtifactCreate) error { return nil } - // AssertBaseArtifactRequired checks if the required fields are not zero-ed func AssertBaseArtifactRequired(obj model.BaseArtifact) error { elements := map[string]interface{}{ @@ -100,7 +97,6 @@ func AssertBaseArtifactConstraints(obj model.BaseArtifact) error { return nil } - // AssertBaseArtifactUpdateRequired checks if the required fields are not zero-ed func AssertBaseArtifactUpdateRequired(obj model.BaseArtifactUpdate) error { return nil @@ -111,7 +107,6 @@ func AssertBaseArtifactUpdateConstraints(obj model.BaseArtifactUpdate) error { return nil } - // AssertBaseExecutionCreateRequired checks if the required fields are not zero-ed func AssertBaseExecutionCreateRequired(obj model.BaseExecutionCreate) error { return nil @@ -122,7 +117,6 @@ func AssertBaseExecutionCreateConstraints(obj model.BaseExecutionCreate) error { return nil } - // AssertBaseExecutionRequired checks if the required fields are not zero-ed func AssertBaseExecutionRequired(obj model.BaseExecution) error { return nil @@ -133,7 +127,6 @@ func AssertBaseExecutionConstraints(obj model.BaseExecution) error { return nil } - // AssertBaseExecutionUpdateRequired checks if the required fields are not zero-ed func AssertBaseExecutionUpdateRequired(obj model.BaseExecutionUpdate) error { return nil @@ -144,7 +137,6 @@ func AssertBaseExecutionUpdateConstraints(obj model.BaseExecutionUpdate) error { return nil } - // AssertBaseResourceCreateRequired checks if the required fields are not zero-ed func AssertBaseResourceCreateRequired(obj model.BaseResourceCreate) error { return nil @@ -155,7 +147,6 @@ func AssertBaseResourceCreateConstraints(obj model.BaseResourceCreate) error { return nil } - // AssertBaseResourceRequired checks if the required fields are not zero-ed func AssertBaseResourceRequired(obj model.BaseResource) error { return nil @@ -166,7 +157,6 @@ func AssertBaseResourceConstraints(obj model.BaseResource) error { return nil } - // AssertBaseResourceListRequired checks if the required fields are not zero-ed func AssertBaseResourceListRequired(obj model.BaseResourceList) error { elements := map[string]interface{}{ @@ -188,7 +178,6 @@ func AssertBaseResourceListConstraints(obj model.BaseResourceList) error { return nil } - // AssertBaseResourceUpdateRequired checks if the required fields are not zero-ed func AssertBaseResourceUpdateRequired(obj model.BaseResourceUpdate) error { return nil @@ -199,7 +188,6 @@ func AssertBaseResourceUpdateConstraints(obj model.BaseResourceUpdate) error { return nil } - // AssertErrorRequired checks if the required fields are not zero-ed func AssertErrorRequired(obj model.Error) error { elements := map[string]interface{}{ @@ -220,7 +208,6 @@ func AssertErrorConstraints(obj model.Error) error { return nil } - // AssertExecutionStateRequired checks if the required fields are not zero-ed func AssertExecutionStateRequired(obj model.ExecutionState) error { return nil @@ -231,7 +218,6 @@ func AssertExecutionStateConstraints(obj model.ExecutionState) error { return nil } - // AssertInferenceServiceCreateRequired checks if the required fields are not zero-ed func AssertInferenceServiceCreateRequired(obj model.InferenceServiceCreate) error { elements := map[string]interface{}{ @@ -252,7 +238,6 @@ func AssertInferenceServiceCreateConstraints(obj model.InferenceServiceCreate) e return nil } - // AssertInferenceServiceRequired checks if the required fields are not zero-ed func AssertInferenceServiceRequired(obj model.InferenceService) error { return nil @@ -263,7 +248,6 @@ func AssertInferenceServiceConstraints(obj model.InferenceService) error { return nil } - // AssertInferenceServiceListRequired checks if the required fields are not zero-ed func AssertInferenceServiceListRequired(obj model.InferenceServiceList) error { elements := map[string]interface{}{ @@ -290,7 +274,6 @@ func AssertInferenceServiceListConstraints(obj model.InferenceServiceList) error return nil } - // AssertInferenceServiceUpdateRequired checks if the required fields are not zero-ed func AssertInferenceServiceUpdateRequired(obj model.InferenceServiceUpdate) error { return nil @@ -301,7 +284,6 @@ func AssertInferenceServiceUpdateConstraints(obj model.InferenceServiceUpdate) e return nil } - // AssertMetadataValueRequired checks if the required fields are not zero-ed func AssertMetadataValueRequired(obj model.MetadataValue) error { return nil @@ -312,7 +294,6 @@ func AssertMetadataValueConstraints(obj model.MetadataValue) error { return nil } - // AssertModelArtifactCreateRequired checks if the required fields are not zero-ed func AssertModelArtifactCreateRequired(obj model.ModelArtifactCreate) error { return nil @@ -323,7 +304,6 @@ func AssertModelArtifactCreateConstraints(obj model.ModelArtifactCreate) error { return nil } - // AssertModelArtifactRequired checks if the required fields are not zero-ed func AssertModelArtifactRequired(obj model.ModelArtifact) error { elements := map[string]interface{}{ @@ -343,7 +323,6 @@ func AssertModelArtifactConstraints(obj model.ModelArtifact) error { return nil } - // AssertModelArtifactListRequired checks if the required fields are not zero-ed func AssertModelArtifactListRequired(obj model.ModelArtifactList) error { elements := map[string]interface{}{ From 2c36e23bdf2387b4a49d4e47840d5d93e8b08788 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Mon, 23 Oct 2023 21:00:58 +0200 Subject: [PATCH 068/254] Setup image build and push to quay (#72) * Setup image build and push to quay * Skip docke login if we skip the push * Extract build and deploy steps in a dedicated script --- .github/workflows/build-image-main.yml | 51 ++++++++++++++++++ .github/workflows/build-image-pr.yml | 27 ++++++++++ .github/workflows/container-image.yml | 15 ------ Makefile | 31 +++++++++++ scripts/build_deploy.sh | 72 ++++++++++++++++++++++++++ 5 files changed, 181 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/build-image-main.yml create mode 100644 .github/workflows/build-image-pr.yml delete mode 100644 .github/workflows/container-image.yml create mode 100755 scripts/build_deploy.sh diff --git a/.github/workflows/build-image-main.yml b/.github/workflows/build-image-main.yml new file mode 100644 index 00000000..4ec2a0ba --- /dev/null +++ b/.github/workflows/build-image-main.yml @@ -0,0 +1,51 @@ +name: Main container image build and tag + +on: + push: + branches: [ 'main' ] + +env: + QUAY_IMG_REPO: model-registry + QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} + QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }} + PUSH_IMAGE: true + +jobs: + build-image: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Generate Tag + shell: bash + id: tags + run: | + commit_sha=${{ github.event.after }} + tag=main-${commit_sha:0:7} + echo "tag=${tag}" >> $GITHUB_OUTPUT + - name: Build and Push Image + shell: bash + env: + VERSION: ${{ steps.tags.outputs.tag }} + run: ./scripts/build_deploy.sh + - name: Tag Latest + shell: bash + env: + IMG: quay.io/${{ env.QUAY_ORG }}/${{ env.QUAY_IMG_REPO }} + BUILD_IMAGE: false + NEWEST_TAG: ${{ steps.tags.outputs.tag }} + VERSION: latest + run: | + docker tag ${{ env.IMG }}:${{ env.NEWEST_TAG }} ${{ env.IMG }}:${{ env.VERSION }} + # BUILD_IMAGE=false skip the build + ./scripts/build_deploy.sh + - name: Tag Main + shell: bash + env: + IMG: quay.io/${{ env.QUAY_ORG }}/${{ env.QUAY_IMG_REPO }} + BUILD_IMAGE: false + NEWEST_TAG: ${{ steps.tags.outputs.tag }} + VERSION: main + run: | + docker tag ${{ env.IMG }}:${{ env.NEWEST_TAG }} ${{ env.IMG }}:${{ env.VERSION }} + # BUILD_IMAGE=false skip the build + ./scripts/build_deploy.sh diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml new file mode 100644 index 00000000..008ae021 --- /dev/null +++ b/.github/workflows/build-image-pr.yml @@ -0,0 +1,27 @@ +name: Test container image build + +on: + pull_request_target: + branches: [ '*' ] + +env: + QUAY_IMG_REPO: model-registry + PUSH_IMAGE: false + +jobs: + build-image: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Generate Tag + shell: bash + id: tags + run: | + commit_sha=${{ github.event.after }} + tag=main-${commit_sha:0:7} + echo "tag=${tag}" >> $GITHUB_OUTPUT + - name: Build Image + shell: bash + env: + VERSION: ${{ steps.tags.outputs.tag }} + run: ./scripts/build_deploy.sh \ No newline at end of file diff --git a/.github/workflows/container-image.yml b/.github/workflows/container-image.yml deleted file mode 100644 index 27833bbb..00000000 --- a/.github/workflows/container-image.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Test Container Image build - -on: - push: - branches: [ 'main' ] - pull_request: - branches: [ '*' ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build the Docker image - run: docker build . --file Dockerfile --tag model-registry:$(date +%s) diff --git a/Makefile b/Makefile index 6638beb6..f957b803 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,22 @@ PROJECT_BIN := $(PROJECT_PATH)/bin # add tools bin directory PATH := $(PROJECT_BIN):$(PATH) + +# docker executable +DOCKER ?= docker +# default Dockerfile +DOCKERFILE ?= Dockerfile +# container registry +IMG_REGISTRY ?= quay.io +# container image organization +IMG_ORG ?= opendatahub +# container image version +IMG_VERSION ?= main +# container image repository +IMG_REPO ?= model-registry +# container image +IMG := ${IMG_REGISTRY}/$(IMG_ORG)/$(IMG_REPO) + model-registry: build internal/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto @@ -145,4 +161,19 @@ run/client: gen serve: build ./model-registry serve --logtostderr=true +# login to docker +.PHONY: docker/login +docker/login: + $(DOCKER) login -u "${DOCKER_USER}" -p "${DOCKER_PWD}" "${IMG_REGISTRY}" + +# build docker image +.PHONY: image/build +image/build: + ${DOCKER} build . -f ${DOCKERFILE} -t ${IMG}:$(IMG_VERSION) + +# push docker image +.PHONY: image/push +image/push: + ${DOCKER} push ${IMG}:$(IMG_VERSION) + all: model-registry diff --git a/scripts/build_deploy.sh b/scripts/build_deploy.sh new file mode 100755 index 00000000..9855569f --- /dev/null +++ b/scripts/build_deploy.sh @@ -0,0 +1,72 @@ +#!/bin/bash + +set -e + +# quay.io credentials +QUAY_REGISTRY=quay.io +QUAY_ORG="${QUAY_ORG:-opendatahub}" +QUAY_IMG_REPO="${QUAY_IMG_REPO:-model-registry}" +QUAY_USERNAME="${QUAY_USERNAME}" +QUAY_PASSWORD="${QUAY_PASSWORD}" + +# image version +HASH="$(git rev-parse --short=7 HEAD)" +VERSION="${VERSION:-$HASH}" + +# if set to 0 skip image build +# otherwise build it +BUILD_IMAGE="${BUILD_IMAGE:-true}" + +# if set to 0 skip push to registry +# otherwise push it +PUSH_IMAGE="${PUSH_IMAGE:-false}" + +# skip if image already existing on registry +SKIP_IF_EXISTING="${SKIP_IF_EXISTING:-false}" + +# assure docker exists +docker -v foo >/dev/null 2>&1 || { echo >&2 "::error:: Docker is required. Aborting."; exit 1; } + +# skip if image already existing +if [[ "${SKIP_IF_EXISTING,,}" == "true" ]]; then + TAGS=$(curl --request GET "https://$QUAY_REGISTRY/api/v1/repository/${QUAY_ORG}/${QUAY_IMG_REPO}/tag/?specificTag=${VERSION}") + LATEST_TAG_HAS_END_TS=$(echo $TAGS | jq .tags - | jq 'sort_by(.start_ts) | reverse' | jq '.[0].end_ts') + NOT_EMPTY=$(echo ${TAGS} | jq .tags - | jq any) + + # Image only exists if there is a tag that does not have "end_ts" (i.e. it is still present). + if [[ "$NOT_EMPTY" == "true" && $LATEST_TAG_HAS_END_TS == "null" ]]; then + echo "::error:: The image ${QUAY_ORG}/${QUAY_IMG_REPO}:${VERSION} already exists" + exit 1 + else + echo "Image does not exist...proceeding with build & push." + fi +fi + +# build docker image, login is not required at this step +if [[ "${BUILD_IMAGE,,}" == "true" ]]; then + echo "Building container image.." + make \ + IMG_REGISTRY="${QUAY_REGISTRY}" \ + IMG_ORG="${QUAY_ORG}" \ + IMG_REPO="${QUAY_IMG_REPO}" \ + IMG_VERSION="${VERSION}" \ + image/build +else + echo "Skip container image build." +fi + +# push container image to registry, requires login +if [[ "${PUSH_IMAGE,,}" == "true" ]]; then + echo "Pushing container image.." + make \ + IMG_REGISTRY="${QUAY_REGISTRY}" \ + IMG_ORG="${QUAY_ORG}" \ + IMG_REPO="${QUAY_IMG_REPO}" \ + IMG_VERSION="${VERSION}" \ + DOCKER_USER="${QUAY_USERNAME} "\ + DOCKER_PWD="${QUAY_PASSWORD}" \ + docker/login \ + image/push +else + echo "Skip container image push." +fi \ No newline at end of file From 23fe7edfc6a86f588803fb9634d194f628682880 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Tue, 24 Oct 2023 14:12:47 +0200 Subject: [PATCH 069/254] Metadata mapping OpenAPI/gRPC for Bool and Struct (#84) --- go.mod | 2 +- internal/core/mapper/mlmd_mapper.go | 49 +++++++-- internal/core/mapper/mlmd_mapper_test.go | 125 +++++++++++++++++++++++ 3 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 internal/core/mapper/mlmd_mapper_test.go diff --git a/go.mod b/go.mod index e96d7555..c6384b8e 100644 --- a/go.mod +++ b/go.mod @@ -91,7 +91,7 @@ require ( github.com/urfave/cli/v2 v2.25.5 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect + golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect diff --git a/internal/core/mapper/mlmd_mapper.go b/internal/core/mapper/mlmd_mapper.go index d9572423..71b7e108 100644 --- a/internal/core/mapper/mlmd_mapper.go +++ b/internal/core/mapper/mlmd_mapper.go @@ -1,12 +1,14 @@ package mapper import ( + "encoding/base64" + "encoding/json" "fmt" - "log" "strconv" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" + "google.golang.org/protobuf/types/known/structpb" ) type Mapper struct { @@ -50,12 +52,14 @@ func (m *Mapper) MapToProperties(data map[string]openapi.MetadataValue) (map[str value := proto.Value{} switch { + // bool value + case v.MetadataBoolValue != nil: + value.Value = &proto.Value_BoolValue{BoolValue: *v.MetadataBoolValue.BoolValue} // int value case v.MetadataIntValue != nil: intValue, err := IdToInt64(*v.MetadataIntValue.IntValue) if err != nil { - log.Printf("Skipping mapping for %s:%v", key, v) - continue + return nil, fmt.Errorf("unable to decode as int64 %w for key %s", err, key) } value.Value = &proto.Value_IntValue{IntValue: *intValue} // double value @@ -64,9 +68,26 @@ func (m *Mapper) MapToProperties(data map[string]openapi.MetadataValue) (map[str // string value case v.MetadataStringValue != nil: value.Value = &proto.Value_StringValue{StringValue: *v.MetadataStringValue.StringValue} + // struct value + case v.MetadataStructValue != nil: + data, err := base64.StdEncoding.DecodeString(*v.MetadataStructValue.StructValue) + if err != nil { + return nil, fmt.Errorf("unable to decode %w for key %s", err, key) + } + var asMap map[string]interface{} + err = json.Unmarshal(data, &asMap) + if err != nil { + return nil, fmt.Errorf("unable to decode %w for key %s", err, key) + } + asStruct, err := structpb.NewStruct(asMap) + if err != nil { + return nil, fmt.Errorf("unable to decode %w for key %s", err, key) + } + value.Value = &proto.Value_StructValue{ + StructValue: asStruct, + } default: - log.Printf("Type mapping not found for %s:%v", key, v) - continue + return nil, fmt.Errorf("type mapping not found for %s:%v", key, v) } props[key] = &value @@ -168,6 +189,10 @@ func (m *Mapper) MapFromProperties(props map[string]*proto.Value) (map[string]op customValue := openapi.MetadataValue{} switch typedValue := v.Value.(type) { + case *proto.Value_BoolValue: + customValue.MetadataBoolValue = &openapi.MetadataBoolValue{ + BoolValue: &typedValue.BoolValue, + } case *proto.Value_IntValue: customValue.MetadataIntValue = &openapi.MetadataIntValue{ IntValue: IdToString(typedValue.IntValue), @@ -180,9 +205,19 @@ func (m *Mapper) MapFromProperties(props map[string]*proto.Value) (map[string]op customValue.MetadataStringValue = &openapi.MetadataStringValue{ StringValue: &typedValue.StringValue, } + case *proto.Value_StructValue: + sv := typedValue.StructValue + asMap := sv.AsMap() + asJSON, err := json.Marshal(asMap) + if err != nil { + return nil, err + } + b64 := base64.StdEncoding.EncodeToString(asJSON) + customValue.MetadataStructValue = &openapi.MetadataStructValue{ + StructValue: &b64, + } default: - log.Printf("Type mapping not found for %s:%v", key, v) - continue + return nil, fmt.Errorf("type mapping not found for %s:%v", key, v) } data[key] = customValue diff --git a/internal/core/mapper/mlmd_mapper_test.go b/internal/core/mapper/mlmd_mapper_test.go new file mode 100644 index 00000000..d9203475 --- /dev/null +++ b/internal/core/mapper/mlmd_mapper_test.go @@ -0,0 +1,125 @@ +package mapper_test + +import ( + "encoding/base64" + "encoding/json" + "testing" + + "github.com/opendatahub-io/model-registry/internal/core/mapper" + "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/stretchr/testify/assert" + "golang.org/x/exp/maps" +) + +func TestMetadataValueBool(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my bool" + mdValue := true + data[key] = openapi.MetadataBoolValueAsMetadataValue(&openapi.MetadataBoolValue{BoolValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueInt(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my int" + mdValue := "987" + data[key] = openapi.MetadataIntValueAsMetadataValue(&openapi.MetadataIntValue{IntValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueIntFailure(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my int" + mdValue := "not a number" + data[key] = openapi.MetadataIntValueAsMetadataValue(&openapi.MetadataIntValue{IntValue: &mdValue}) + + mapper, assert := setup(t) + asGRPC, err := mapper.MapToProperties(data) + if err == nil { + assert.Fail("Did not expected a converted value but an error: %v", asGRPC) + } +} + +func TestMetadataValueDouble(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my double" + mdValue := 3.1415 + data[key] = openapi.MetadataDoubleValueAsMetadataValue(&openapi.MetadataDoubleValue{DoubleValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueString(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my string" + mdValue := "Hello, World!" + data[key] = openapi.MetadataStringValueAsMetadataValue(&openapi.MetadataStringValue{StringValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueStruct(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my struct" + + myMap := make(map[string]interface{}) + myMap["name"] = "John Doe" + myMap["age"] = 47 + asJSON, err := json.Marshal(myMap) + if err != nil { + t.Error(err) + } + b64 := base64.StdEncoding.EncodeToString(asJSON) + data[key] = openapi.MetadataStructValueAsMetadataValue(&openapi.MetadataStructValue{StructValue: &b64}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueProtoUnsupported(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my proto" + + myMap := make(map[string]interface{}) + myMap["name"] = "John Doe" + myMap["age"] = 47 + asJSON, err := json.Marshal(myMap) + if err != nil { + t.Error(err) + } + b64 := base64.StdEncoding.EncodeToString(asJSON) + typeDef := "map[string]openapi.MetadataValue" + data[key] = openapi.MetadataProtoValueAsMetadataValue(&openapi.MetadataProtoValue{ + Type: &typeDef, + ProtoValue: &b64, + }) + + mapper, assert := setup(t) + asGRPC, err := mapper.MapToProperties(data) + if err == nil { + assert.Fail("Did not expected a converted value but an error: %v", asGRPC) + } +} + +func roundTripAndAssert(t *testing.T, data map[string]openapi.MetadataValue, key string) { + mapper, assert := setup(t) + + // first half + asGRPC, err := mapper.MapToProperties(data) + if err != nil { + t.Error(err) + } + assert.Contains(maps.Keys(asGRPC), key) + + // second half + unmarshall, err := mapper.MapFromProperties(asGRPC) + if err != nil { + t.Error(err) + } + assert.Equal(data, unmarshall, "result of round-trip shall be equal to original data") +} + +func setup(t *testing.T) (*mapper.Mapper, *assert.Assertions) { + return mapper.NewMapper(1, 2, 3), assert.New(t) +} From 4a16cab4006db89bc3dccbdc83a408fbac8eb74c Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Wed, 25 Oct 2023 09:31:46 +0200 Subject: [PATCH 070/254] Manage prefix for owned entities (#79) * Make use of registeredModelID for ModelVersion * Manage Artifact prefix and naming * Rename parameters per code review --- go.mod | 2 +- internal/core/api.go | 18 +++++------ internal/core/core.go | 42 ++++++++++++------------- internal/core/mapper/mlmd_mapper.go | 48 +++++++++++++++++++++++------ 4 files changed, 70 insertions(+), 40 deletions(-) diff --git a/go.mod b/go.mod index c6384b8e..0a707d13 100644 --- a/go.mod +++ b/go.mod @@ -54,7 +54,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/uuid v1.3.1 // indirect + github.com/google/uuid v1.3.1 github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect diff --git a/internal/core/api.go b/internal/core/api.go index a88a899f..1dd29f1f 100644 --- a/internal/core/api.go +++ b/internal/core/api.go @@ -26,20 +26,20 @@ type ModelRegistryApi interface { // MODEL VERSION // Create a new Model Version - // or update a Model Version associated to a specific RegisteredModel identified by registeredModelId parameter - UpsertModelVersion(modelVersion *openapi.ModelVersion, registeredModelId *BaseResourceId) (*openapi.ModelVersion, error) + // or update a Model Version associated to a specific RegisteredModel identified by parentResourceId parameter + UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *BaseResourceId) (*openapi.ModelVersion, error) GetModelVersionById(id *BaseResourceId) (*openapi.ModelVersion, error) - GetModelVersionByParams(name *string, externalId *string) (*openapi.ModelVersion, error) - GetModelVersions(listOptions ListOptions, registeredModelId *BaseResourceId) (*openapi.ModelVersionList, error) + GetModelVersionByParams(versionName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelVersion, error) + GetModelVersions(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelVersionList, error) // MODEL ARTIFACT - // Create or update a Model Artifact associated to a specific ModelVersion - // identified by ModelArtifact.ModelVersionId - UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *BaseResourceId) (*openapi.ModelArtifact, error) + // Create a new Artifact + // or update an Artifact associated to a specific ModelVersion identified by parentResourceId parameter + UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *BaseResourceId) (*openapi.ModelArtifact, error) GetModelArtifactById(id *BaseResourceId) (*openapi.ModelArtifact, error) - GetModelArtifactByParams(name *string, externalId *string) (*openapi.ModelArtifact, error) - GetModelArtifacts(listOptions ListOptions, modelVersionId *BaseResourceId) (*openapi.ModelArtifactList, error) + GetModelArtifactByParams(artifactName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelArtifact, error) + GetModelArtifacts(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelArtifactList, error) } diff --git a/internal/core/core.go b/internal/core/core.go index e0cf9752..0453d4b2 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -191,10 +191,10 @@ func (serv *modelRegistryService) GetRegisteredModels(listOptions ListOptions) ( // MODEL VERSIONS -func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, registeredModelId *BaseResourceId) (*openapi.ModelVersion, error) { - registeredModel, err := serv.GetRegisteredModelById(registeredModelId) +func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *BaseResourceId) (*openapi.ModelVersion, error) { + registeredModel, err := serv.GetRegisteredModelById(parentResourceId) if err != nil { - return nil, fmt.Errorf("not a valid registered model id: %d", *registeredModelId) + return nil, fmt.Errorf("not a valid registered model id: %d", *parentResourceId) } registeredModelIdCtxID, err := mapper.IdToInt64(*registeredModel.Id) if err != nil { @@ -254,10 +254,10 @@ func (serv *modelRegistryService) GetModelVersionById(id *BaseResourceId) (*open return modelVer, nil } -func (serv *modelRegistryService) GetModelVersionByParams(name *string, externalId *string) (*openapi.ModelVersion, error) { +func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelVersion, error) { filterQuery := "" - if name != nil { - filterQuery = fmt.Sprintf("name = \"%s\"", *name) + if versionName != nil && parentResourceId != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned((*int64)(parentResourceId), *versionName)) } else if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) } @@ -273,7 +273,7 @@ func (serv *modelRegistryService) GetModelVersionByParams(name *string, external } if len(getByParamsResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple registered models found for name=%v, externalId=%v", *name, *externalId) + return nil, fmt.Errorf("multiple registered models found for versionName=%v, parentResourceId=%v, externalId=%v", zeroIfNil(versionName), zeroIfNil(parentResourceId), zeroIfNil(externalId)) } modelVer, err := serv.mapper.MapToModelVersion(getByParamsResp.Contexts[0]) @@ -283,14 +283,14 @@ func (serv *modelRegistryService) GetModelVersionByParams(name *string, external return modelVer, nil } -func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, registeredModelId *BaseResourceId) (*openapi.ModelVersionList, error) { +func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelVersionList, error) { listOperationOptions, err := BuildListOperationOptions(listOptions) if err != nil { return nil, err } - if registeredModelId != nil { - queryParentCtxId := fmt.Sprintf("parent_contexts_a.type = %d", *registeredModelId) + if parentResourceId != nil { + queryParentCtxId := fmt.Sprintf("parent_contexts_a.type = %d", *parentResourceId) listOperationOptions.FilterQuery = &queryParentCtxId } @@ -322,8 +322,8 @@ func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, regi // MODEL ARTIFACTS -func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *BaseResourceId) (*openapi.ModelArtifact, error) { - artifact := serv.mapper.MapFromModelArtifact(*modelArtifact) +func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *BaseResourceId) (*openapi.ModelArtifact, error) { + artifact := serv.mapper.MapFromModelArtifact(*modelArtifact, (*int64)(parentResourceId)) artifactsResp, err := serv.mlmdClient.PutArtifacts(context.Background(), &proto.PutArtifactsRequest{ Artifacts: []*proto.Artifact{artifact}, @@ -335,8 +335,8 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod modelArtifact.Id = &idString // add explicit association between artifacts and model version - if modelVersionId != nil { - modelVersionIdCtx := int64(*modelVersionId) + if parentResourceId != nil { + modelVersionIdCtx := int64(*parentResourceId) attributions := []*proto.Attribution{} for _, a := range artifactsResp.ArtifactIds { attributions = append(attributions, &proto.Attribution{ @@ -372,16 +372,16 @@ func (serv *modelRegistryService) GetModelArtifactById(id *BaseResourceId) (*ope return result, nil } -func (serv *modelRegistryService) GetModelArtifactByParams(name *string, externalId *string) (*openapi.ModelArtifact, error) { +func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelArtifact, error) { var artifact0 *proto.Artifact filterQuery := "" if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) - } else if name != nil { - filterQuery = fmt.Sprintf("name = \"%s\"", *name) + } else if artifactName != nil && parentResourceId != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned((*int64)(parentResourceId), *artifactName)) } else { - return nil, fmt.Errorf("invalid parameters call, supply either name or externalId") + return nil, fmt.Errorf("invalid parameters call, supply either (artifactName and parentResourceId), or externalId") } artifactsResponse, err := serv.mlmdClient.GetArtifactsByType(context.Background(), &proto.GetArtifactsByTypeRequest{ @@ -406,7 +406,7 @@ func (serv *modelRegistryService) GetModelArtifactByParams(name *string, externa return result, nil } -func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, modelVersionId *BaseResourceId) (*openapi.ModelArtifactList, error) { +func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelArtifactList, error) { listOperationOptions, err := BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -414,8 +414,8 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, mod var artifacts []*proto.Artifact var nextPageToken *string - if modelVersionId != nil { - ctxId := int64(*modelVersionId) + if parentResourceId != nil { + ctxId := int64(*parentResourceId) artifactsResp, err := serv.mlmdClient.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ ContextId: &ctxId, Options: listOperationOptions, diff --git a/internal/core/mapper/mlmd_mapper.go b/internal/core/mapper/mlmd_mapper.go index 71b7e108..f4d0589a 100644 --- a/internal/core/mapper/mlmd_mapper.go +++ b/internal/core/mapper/mlmd_mapper.go @@ -5,7 +5,9 @@ import ( "encoding/json" "fmt" "strconv" + "strings" + "github.com/google/uuid" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" "google.golang.org/protobuf/types/known/structpb" @@ -122,7 +124,7 @@ func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel } func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registeredModelId int64, registeredModelName *string) (*proto.Context, error) { - fullName := fmt.Sprintf("%d:%s", registeredModelId, *modelVersion.Name) + fullName := PrefixWhenOwned(®isteredModelId, *modelVersion.Name) customProps := make(map[string]*proto.Value) if modelVersion.CustomProperties != nil { customProps, _ = m.MapToProperties(*modelVersion.CustomProperties) @@ -158,22 +160,30 @@ func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registe return ctx, nil } -func (m *Mapper) MapFromModelArtifact(modelArtifact openapi.ModelArtifact) *proto.Artifact { +func (m *Mapper) MapFromModelArtifact(modelArtifact openapi.ModelArtifact, modelVersionId *int64) *proto.Artifact { + // openapi.Artifact is defined with optional name, so build arbitrary name for this artifact if missing + var artifactName string + if modelArtifact.Name != nil { + artifactName = *modelArtifact.Name + } else { + artifactName = uuid.New().String() + } + // build fullName for mlmd storage + fullName := PrefixWhenOwned(modelVersionId, artifactName) return &proto.Artifact{ TypeId: &m.ModelArtifactTypeId, - // TODO: we should use concatenation between uuid + name - Name: modelArtifact.Name, - Uri: modelArtifact.Uri, + Name: &fullName, + Uri: modelArtifact.Uri, } } -func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact) ([]*proto.Artifact, error) { +func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact, modelVersionId *int64) ([]*proto.Artifact, error) { artifacts := []*proto.Artifact{} if modelArtifacts == nil { return artifacts, nil } for _, a := range *modelArtifacts { - artifacts = append(artifacts, m.MapFromModelArtifact(a)) + artifacts = append(artifacts, m.MapFromModelArtifact(a, modelVersionId)) } return artifacts, nil } @@ -263,10 +273,11 @@ func (m *Mapper) MapToModelVersion(ctx *proto.Context) (*openapi.ModelVersion, e idString := strconv.FormatInt(*ctx.Id, 10) + name := NameFromOwned(*ctx.Name) modelVersion := &openapi.ModelVersion{ // ModelName: &modelName, Id: &idString, - Name: ctx.Name, + Name: &name, // Author: &author, CustomProperties: &metadata, } @@ -289,10 +300,29 @@ func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArt return nil, err } + name := NameFromOwned(*artifact.Name) modelArtifact := &openapi.ModelArtifact{ Uri: artifact.Uri, - Name: artifact.Name, + Name: &name, } return modelArtifact, nil } + +// For owned entity such as ModelVersion +// for potentially owned entity such as ModelArtifact +// compose the mlmd fullname by using ownerId as prefix +func PrefixWhenOwned(ownerId *int64, entityName string) string { + if ownerId != nil { + return fmt.Sprintf("%d:%s", *ownerId, entityName) + } + uuidPrefix := uuid.New().String() + return fmt.Sprintf("%s:%s", uuidPrefix, entityName) +} + +// For owned entity such as ModelVersion +// for potentially owned entity such as ModelArtifact +// derive the entity name from the mlmd fullname +func NameFromOwned(fullName string) string { + return strings.Split(fullName, ":")[1] +} From d53fd864117881304e1bf525db0aba51121a87eb Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Wed, 25 Oct 2023 09:32:32 +0200 Subject: [PATCH 071/254] Add in REST findModelArtifact modelVersionID query param (#81) * Add in REST findModelArtifact modelVersionID query param * Rename parameters per code review --- api/openapi/model-registry.yaml | 12 +++--- .../openapi/api_model_registry_service.go | 38 ++++++++++++------- 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index bb065ca9..44bc985d 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -37,6 +37,8 @@ paths: $ref: '#/components/parameters/name' - $ref: '#/components/parameters/externalID' + - + $ref: '#/components/parameters/parentResourceID' /api/model_registry/v1alpha1/model_artifacts: summary: Path used to manage the list of modelartifacts. description: >- @@ -982,7 +984,7 @@ paths: - $ref: '#/components/parameters/externalID' - - $ref: '#/components/parameters/registeredModelID' + $ref: '#/components/parameters/parentResourceID' components: schemas: ArtifactState: @@ -1678,12 +1680,12 @@ components: type: string in: query required: false - registeredModelID: + parentResourceID: examples: - registeredModelID: + parentResourceID: value: '10' - name: registeredModelID - description: ID of the `RegisteredModel` to use for search. + name: parentResourceID + description: ID of the parent resource to use for search. schema: type: string in: query diff --git a/internal/model/openapi/api_model_registry_service.go b/internal/model/openapi/api_model_registry_service.go index cc1129df..839c3106 100644 --- a/internal/model/openapi/api_model_registry_service.go +++ b/internal/model/openapi/api_model_registry_service.go @@ -1542,10 +1542,11 @@ func (a *ModelRegistryServiceAPIService) FindInferenceServiceExecute(r ApiFindIn } type ApiFindModelArtifactRequest struct { - ctx context.Context - ApiService *ModelRegistryServiceAPIService - name *string - externalID *string + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string + parentResourceID *string } // Name of entity to search. @@ -1560,6 +1561,12 @@ func (r ApiFindModelArtifactRequest) ExternalID(externalID string) ApiFindModelA return r } +// ID of the parent resource to use for search. +func (r ApiFindModelArtifactRequest) ParentResourceID(parentResourceID string) ApiFindModelArtifactRequest { + r.parentResourceID = &parentResourceID + return r +} + func (r ApiFindModelArtifactRequest) Execute() (*ModelArtifact, *http.Response, error) { return r.ApiService.FindModelArtifactExecute(r) } @@ -1607,6 +1614,9 @@ func (a *ModelRegistryServiceAPIService) FindModelArtifactExecute(r ApiFindModel if r.externalID != nil { parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") } + if r.parentResourceID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "parentResourceID", r.parentResourceID, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} @@ -1705,11 +1715,11 @@ func (a *ModelRegistryServiceAPIService) FindModelArtifactExecute(r ApiFindModel } type ApiFindModelVersionRequest struct { - ctx context.Context - ApiService *ModelRegistryServiceAPIService - name *string - externalID *string - registeredModelID *string + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string + parentResourceID *string } // Name of entity to search. @@ -1724,9 +1734,9 @@ func (r ApiFindModelVersionRequest) ExternalID(externalID string) ApiFindModelVe return r } -// ID of the `RegisteredModel` to use for search. -func (r ApiFindModelVersionRequest) RegisteredModelID(registeredModelID string) ApiFindModelVersionRequest { - r.registeredModelID = ®isteredModelID +// ID of the parent resource to use for search. +func (r ApiFindModelVersionRequest) ParentResourceID(parentResourceID string) ApiFindModelVersionRequest { + r.parentResourceID = &parentResourceID return r } @@ -1777,8 +1787,8 @@ func (a *ModelRegistryServiceAPIService) FindModelVersionExecute(r ApiFindModelV if r.externalID != nil { parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") } - if r.registeredModelID != nil { - parameterAddToHeaderOrQuery(localVarQueryParams, "registeredModelID", r.registeredModelID, "") + if r.parentResourceID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "parentResourceID", r.parentResourceID, "") } // to determine the Content-Type header localVarHTTPContentTypes := []string{} From 93359823d506fcb309893331075f68aae2b3629a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 06:49:22 +0000 Subject: [PATCH 072/254] Bump google.golang.org/grpc from 1.57.0 to 1.57.1 (#86) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0a707d13..e9a0e356 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/testcontainers/testcontainers-go v0.25.0 github.com/vektah/gqlparser/v2 v2.5.8 golang.org/x/sync v0.3.0 - google.golang.org/grpc v1.57.0 + google.golang.org/grpc v1.57.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 04a12840..0c421ef3 100644 --- a/go.sum +++ b/go.sum @@ -648,8 +648,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= +google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From 744273c6a7232d5abd138a1cf92f917dfb49eec3 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 26 Oct 2023 14:10:53 +0200 Subject: [PATCH 073/254] Export QUAY_ORG for latest tag (#88) --- .github/workflows/build-image-main.yml | 1 + scripts/build_deploy.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-image-main.yml b/.github/workflows/build-image-main.yml index 4ec2a0ba..4bbd1e79 100644 --- a/.github/workflows/build-image-main.yml +++ b/.github/workflows/build-image-main.yml @@ -5,6 +5,7 @@ on: branches: [ 'main' ] env: + QUAY_ORG: opendatahub QUAY_IMG_REPO: model-registry QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }} diff --git a/scripts/build_deploy.sh b/scripts/build_deploy.sh index 9855569f..5f066110 100755 --- a/scripts/build_deploy.sh +++ b/scripts/build_deploy.sh @@ -63,7 +63,7 @@ if [[ "${PUSH_IMAGE,,}" == "true" ]]; then IMG_ORG="${QUAY_ORG}" \ IMG_REPO="${QUAY_IMG_REPO}" \ IMG_VERSION="${VERSION}" \ - DOCKER_USER="${QUAY_USERNAME} "\ + DOCKER_USER="${QUAY_USERNAME}"\ DOCKER_PWD="${QUAY_PASSWORD}" \ docker/login \ image/push From eb05f45c1144412770784a3b21f76ada471c2fef Mon Sep 17 00:00:00 2001 From: Ramesh Reddy Date: Thu, 26 Oct 2023 11:31:37 -0500 Subject: [PATCH 074/254] Adding the tracker template for issue creation (#91) Signed-off-by: Ramesh Reddy --- .github/ISSUE_TEMPLATE/tracker.md | 64 +++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/tracker.md diff --git a/.github/ISSUE_TEMPLATE/tracker.md b/.github/ISSUE_TEMPLATE/tracker.md new file mode 100644 index 00000000..aa89c3eb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/tracker.md @@ -0,0 +1,64 @@ +name: (Internal) Tracker Template +description: Intended to help with a template for tracking larger grouped items. +title: "[Tracker]: " +labels: ["tracker"] +body: + - type: textarea + id: description + attributes: + label: Description + description: A introductory description of the larger task + validations: + required: + true + - type: input + id: branch + attributes: + label: Target Branch + description: What is the feature branch to contain this effort? If not known at this time, replace with `TBD` + placeholder: f/ + validations: + required: true + - type: textarea + id: requirements + attributes: + label: Requirements + description: A series of requirements to consider this tracker complete. + placeholder: | + * P0: Show something + * P2: Allow users to change permissions + validations: + required: true + - type: textarea + id: ux-issues + attributes: + label: Itemized UX Issues + description: | + List the tickets that UX will work on. + + Tip: Using a bullet list will help display links to other tickets by unraveling the name and status of that ticket. + placeholder: | + * #1234 + * Design mocks - Ticket TBD + validations: + required: true + - type: textarea + id: dev-issues + attributes: + label: Itemized Dev Issues + description: | + List the tickets that Development will work on. If unknown at this time, add `TBD` + + Tip: Using a bullet list will help display links to other tickets by unraveling the name and status of that ticket. + placeholder: | + * #1234 + * Implement Table Page - Ticket TBD + validations: + required: true + - type: textarea + id: artifacts + attributes: + label: Related artifacts + description: Any additional artifacts that will help with the tracker goals + validations: + required: false \ No newline at end of file From c2213f3da37a57d7fa5cde0d8dda1e2703743fbd Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Thu, 26 Oct 2023 18:42:29 +0200 Subject: [PATCH 075/254] Rename tracker.md to tracker.yml (#92) followup to https://github.com/opendatahub-io/model-registry/pull/91#issuecomment-1781466843 --- .github/ISSUE_TEMPLATE/{tracker.md => tracker.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/ISSUE_TEMPLATE/{tracker.md => tracker.yml} (98%) diff --git a/.github/ISSUE_TEMPLATE/tracker.md b/.github/ISSUE_TEMPLATE/tracker.yml similarity index 98% rename from .github/ISSUE_TEMPLATE/tracker.md rename to .github/ISSUE_TEMPLATE/tracker.yml index aa89c3eb..4345f621 100644 --- a/.github/ISSUE_TEMPLATE/tracker.md +++ b/.github/ISSUE_TEMPLATE/tracker.yml @@ -61,4 +61,4 @@ body: label: Related artifacts description: Any additional artifacts that will help with the tracker goals validations: - required: false \ No newline at end of file + required: false From e46529ce675d868c4b39a713e19c28246a88dcdc Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 26 Oct 2023 12:59:37 -0700 Subject: [PATCH 076/254] Create dependabot.yml (#94) * Create dependabot.yml Enable dependabot version updates. * Update dependabot.yml Added Python pip package-ecosystem. --- .github/dependabot.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..93d113cb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,23 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" From 1a03b4cd123c60e63007c156f8d45e7e04eac118 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 06:41:51 +0000 Subject: [PATCH 077/254] Bump ubi8/ubi-minimal from 8.6 to 8.8 (#97) --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index d18777c1..74e49bb6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,7 +37,7 @@ RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 make clean model-registry # Use distroless as minimal base image to package the model-registry binary # Refer to https://github.com/GoogleContainerTools/distroless for more details -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.6 +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 WORKDIR / # copy the metadata library COPY --from=builder /workspace/config ./config From 67ba664f59d145d7db65d5c62908e1bf38ff8e8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 06:42:57 +0000 Subject: [PATCH 078/254] Bump actions/checkout from 3 to 4 (#98) --- .github/workflows/build-image-main.yml | 2 +- .github/workflows/build-image-pr.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-image-main.yml b/.github/workflows/build-image-main.yml index 4bbd1e79..02bb17f2 100644 --- a/.github/workflows/build-image-main.yml +++ b/.github/workflows/build-image-main.yml @@ -15,7 +15,7 @@ jobs: build-image: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Generate Tag shell: bash id: tags diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index 008ae021..67342ce3 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -12,7 +12,7 @@ jobs: build-image: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Generate Tag shell: bash id: tags From 14bfc9b48ea5d512ef93314f287652d147f9903e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 06:44:07 +0000 Subject: [PATCH 079/254] Bump github.com/vektah/gqlparser/v2 from 2.5.8 to 2.5.10 (#99) --- go.mod | 2 +- go.sum | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/go.mod b/go.mod index e9a0e356..60ea337c 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/spf13/viper v1.16.0 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.25.0 - github.com/vektah/gqlparser/v2 v2.5.8 + github.com/vektah/gqlparser/v2 v2.5.10 golang.org/x/sync v0.3.0 google.golang.org/grpc v1.57.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 diff --git a/go.sum b/go.sum index 0c421ef3..bf7b0c75 100644 --- a/go.sum +++ b/go.sum @@ -52,7 +52,6 @@ github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDur github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= @@ -278,7 +277,6 @@ github.com/searKing/golang/tools/go-enum v1.2.97 h1:mX396oCnjdGqmMmwffBwpEU3L1X/ github.com/searKing/golang/tools/go-enum v1.2.97/go.mod h1:gWZ/vkIPpA0nCHDMETjzKqsHPDWSPdhZeXPxf/jWyqA= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -329,8 +327,8 @@ github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9f github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc= github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= -github.com/vektah/gqlparser/v2 v2.5.8 h1:pm6WOnGdzFOCfcQo9L3+xzW51mKrlwTEg4Wr7AH1JW4= -github.com/vektah/gqlparser/v2 v2.5.8/go.mod h1:z8xXUff237NntSuH8mLFijZ+1tjV1swDbpDqjJmk6ME= +github.com/vektah/gqlparser/v2 v2.5.10 h1:6zSM4azXC9u4Nxy5YmdmGu4uKamfwsdKTwp5zsEealU= +github.com/vektah/gqlparser/v2 v2.5.10/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= @@ -669,7 +667,6 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -677,7 +674,6 @@ gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From cf10dfcec18ea6e8e8d2475f8efeaf4fe6f167e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 06:46:41 +0000 Subject: [PATCH 080/254] Bump gorm.io/gorm from 1.25.4 to 1.25.5 (#103) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 60ea337c..a9d72a2f 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/sqlite v1.5.3 - gorm.io/gorm v1.25.4 + gorm.io/gorm v1.25.5 ) require ( diff --git a/go.sum b/go.sum index bf7b0c75..6148a39a 100644 --- a/go.sum +++ b/go.sum @@ -679,8 +679,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlite v1.5.3 h1:7/0dUgX28KAcopdfbRWWl68Rflh6osa4rDh+m51KL2g= gorm.io/driver/sqlite v1.5.3/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= -gorm.io/gorm v1.25.4 h1:iyNd8fNAe8W9dvtlgeRI5zSVZPsq3OpcTu37cYcpCmw= -gorm.io/gorm v1.25.4/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= +gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= From 1914ba4982d2a700248a843227adacb773e76bad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 06:49:15 +0000 Subject: [PATCH 081/254] Bump golang.org/x/sync from 0.3.0 to 0.4.0 (#101) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index a9d72a2f..b2abea71 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.25.0 github.com/vektah/gqlparser/v2 v2.5.10 - golang.org/x/sync v0.3.0 + golang.org/x/sync v0.4.0 google.golang.org/grpc v1.57.1 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 diff --git a/go.sum b/go.sum index 6148a39a..acd21505 100644 --- a/go.sum +++ b/go.sum @@ -443,8 +443,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= +golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From 240bed671aedd41950f008f4c67d59b624a6b9a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 06:55:05 +0000 Subject: [PATCH 082/254] Bump google.golang.org/grpc from 1.57.1 to 1.59.0 (#102) --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index b2abea71..edc05e50 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/99designs/gqlgen v0.17.36 github.com/go-chi/chi/v5 v5.0.10 - github.com/golang/glog v1.1.0 + github.com/golang/glog v1.1.2 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 github.com/searKing/golang/tools/go-enum v1.2.97 github.com/soheilhy/cmux v0.1.5 @@ -16,7 +16,7 @@ require ( github.com/testcontainers/testcontainers-go v0.25.0 github.com/vektah/gqlparser/v2 v2.5.10 golang.org/x/sync v0.4.0 - google.golang.org/grpc v1.57.1 + google.golang.org/grpc v1.59.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 @@ -97,6 +97,6 @@ require ( golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.9.3 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index acd21505..fb53f8a2 100644 --- a/go.sum +++ b/go.sum @@ -123,8 +123,8 @@ github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRx github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= +github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -628,8 +628,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -646,8 +646,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= -google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= +google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= From 9966a13b7047af0d1db3229d712173c7452386c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 07:28:28 +0000 Subject: [PATCH 083/254] Bump github.com/spf13/viper from 1.16.0 to 1.17.0 (#100) --- go.mod | 28 ++++++++++++++++------------ go.sum | 56 +++++++++++++++++++++++++++++++++----------------------- 2 files changed, 49 insertions(+), 35 deletions(-) diff --git a/go.mod b/go.mod index edc05e50..cd0f5557 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.16.0 + github.com/spf13/viper v1.17.0 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.25.0 github.com/vektah/gqlparser/v2 v2.5.10 @@ -27,12 +27,17 @@ require ( require ( github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect github.com/cucumber/messages/go/v21 v21.0.1 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/gofrs/uuid v4.3.1+incompatible // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-memdb v1.3.4 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/sagikazarmark/locafero v0.3.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect ) require ( @@ -61,7 +66,7 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/klauspost/compress v1.16.0 // indirect + github.com/klauspost/compress v1.17.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect @@ -73,7 +78,7 @@ require ( github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opencontainers/runc v1.1.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect @@ -82,21 +87,20 @@ require ( github.com/shirou/gopsutil/v3 v3.23.8 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.0 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cast v1.5.1 // indirect - github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/subosito/gotenv v1.4.2 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/urfave/cli/v2 v2.25.5 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect - golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 - golang.org/x/mod v0.10.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 + golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/sys v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect - golang.org/x/tools v0.9.3 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect + golang.org/x/tools v0.13.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index fb53f8a2..8ae685a1 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,9 @@ github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUt github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= @@ -219,8 +220,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= -github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= +github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -254,13 +255,14 @@ github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/ github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -269,6 +271,10 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= +github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/searKing/golang/go v1.2.52 h1:Nbsr8HIS4ATL7LY1BE3SwRyEQd+UkrRymyol46sXb3s= github.com/searKing/golang/go v1.2.52/go.mod h1:9AhTd9NFW/ck459PgNJwBA6I5q/ZBt9qOSvv9oZvHgA= github.com/searKing/golang/tools v1.2.29 h1:gWX4aCA1+N7CfLpNd6tmBjYtecTksZFXziqbQ+AJKLo= @@ -289,22 +295,23 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0 github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= -github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= -github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= -github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= +github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -312,11 +319,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= -github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/testcontainers/testcontainers-go v0.25.0 h1:erH6cQjsaJrH+rJDU9qIf89KFdhK0Bft0aEZHlYC3Vs= github.com/testcontainers/testcontainers-go v0.25.0/go.mod h1:4sC9SiJyzD1XFi59q8umTQYWxnkweEc5OjVtTUlJzqQ= @@ -345,6 +351,10 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -362,8 +372,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc= -golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -387,8 +397,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -560,8 +570,8 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= -golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -628,8 +638,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= From 52d2151c14eca541ff8187df9df73c2ed60659e6 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 27 Oct 2023 11:15:24 +0200 Subject: [PATCH 084/254] Automate ml-metadata proto download (#89) --- Makefile | 28 + .../ml_metadata/proto/metadata_source.proto | 760 ------------------ 2 files changed, 28 insertions(+), 760 deletions(-) delete mode 100644 api/grpc/ml_metadata/proto/metadata_source.proto diff --git a/Makefile b/Makefile index f957b803..7f7b599d 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ PROJECT_BIN := $(PROJECT_PATH)/bin # add tools bin directory PATH := $(PROJECT_BIN):$(PATH) +MLMD_VERSION ?= 1.14.0 + # docker executable DOCKER ?= docker # default Dockerfile @@ -23,6 +25,32 @@ IMG := ${IMG_REGISTRY}/$(IMG_ORG)/$(IMG_REPO) model-registry: build +# clean the ml-metadata protos and trigger a fresh new build which downloads +# ml-metadata protos based on specified MLMD_VERSION +.PHONY: update/ml_metadata +update/ml_metadata: clean/ml_metadata clean build + +clean/ml_metadata: + rm -rf api/grpc/ml_metadata/proto/*.proto + +api/grpc/ml_metadata/proto/metadata_source.proto: + mkdir -p api/grpc/ml_metadata/proto/ + cd api/grpc/ml_metadata/proto/ && \ + curl -LO "https://raw.githubusercontent.com/google/ml-metadata/v${MLMD_VERSION}/ml_metadata/proto/metadata_source.proto" && \ + sed -i 's#syntax = "proto[23]";#&\noption go_package = "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto";#' metadata_source.proto + +api/grpc/ml_metadata/proto/metadata_store.proto: + mkdir -p api/grpc/ml_metadata/proto/ + cd api/grpc/ml_metadata/proto/ && \ + curl -LO "https://raw.githubusercontent.com/google/ml-metadata/v${MLMD_VERSION}/ml_metadata/proto/metadata_store.proto" && \ + sed -i 's#syntax = "proto[23]";#&\noption go_package = "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto";#' metadata_store.proto + +api/grpc/ml_metadata/proto/metadata_store_service.proto: + mkdir -p api/grpc/ml_metadata/proto/ + cd api/grpc/ml_metadata/proto/ && \ + curl -LO "https://raw.githubusercontent.com/google/ml-metadata/v${MLMD_VERSION}/ml_metadata/proto/metadata_store_service.proto" && \ + sed -i 's#syntax = "proto[23]";#&\noption go_package = "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto";#' metadata_store_service.proto + internal/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto protoc -I./api/grpc --go_out=./internal --go_opt=paths=source_relative \ --go-grpc_out=./internal --go-grpc_opt=paths=source_relative $< diff --git a/api/grpc/ml_metadata/proto/metadata_source.proto b/api/grpc/ml_metadata/proto/metadata_source.proto deleted file mode 100644 index 7798a421..00000000 --- a/api/grpc/ml_metadata/proto/metadata_source.proto +++ /dev/null @@ -1,760 +0,0 @@ -/* Copyright 2019 Google LLC - -Licensed 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 - - https://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. -==============================================================================*/ -// The returned results from a MetadataSource. -syntax = "proto3"; -option go_package = "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto"; - -package ml_metadata; - -import "google/protobuf/any.proto"; - -// A collection of returned records. -message RecordSet { - // An individual record (e.g., row) returned by a MetadataSource. - // The record does not address the type conversion. - message Record { - repeated string values = 1; - } - - // index-aligned column names for all records - repeated string column_names = 1; - - // a list of records returned by a query - repeated Record records = 2; -} - -// Contains supported metadata sources types in MetadataAccessObject. -// Next index: 7 -enum MetadataSourceType { - UNKNOWN_METADATA_SOURCE = 0; - // a fake in memory metadata_source for testing - // DEPRECATED -- use SQLITE_METADATA_SOURCE instead. - FAKE_METADATA_SOURCE = 1; - // a MYSQL metadata source. - MYSQL_METADATA_SOURCE = 2; - // A Sqlite metadata source. - SQLITE_METADATA_SOURCE = 3; - // PostgreSQL, the index number is related to ConnectionConfig. - POSTGRESQL_METADATA_SOURCE = 6; - -} - -// A config includes a set of SQL queries and the type of metadata source. -// It is used by MetadataAccessObject to init backend and issue queries. -// Next ID: 144 -message MetadataSourceQueryConfig { - // the type of the metadata source - MetadataSourceType metadata_source_type = 1; - - // Template of a SQL query, which can contain parameterized variables using - // $0, $1, ... $9. - // For instance: - // query: "select * from foo where bar = $0" - // parameter_num: 1 - message TemplateQuery { - string query = 1; - int32 parameter_num = 2; - } - - // Below is a list of SQL templates queries required for MetadataAccessObject. - // The given SQL should follow conventions in a metadata_source_type. - - // Drops the Type table. - TemplateQuery drop_type_table = 3; - - // Creates the Type table. - TemplateQuery create_type_table = 4; - - // Checks the existence of the Type table. - TemplateQuery check_type_table = 44; - - // Inserts an artifact type into the Type table. It has 3 parameters. - // $0 is the name - // $1 is the version - // $2 is the description - TemplateQuery insert_artifact_type = 54; - - // Inserts an execution type into the Type table. It has 3 parameters. - // $0 is the type name - // $1 is the version - // $2 is the description - // $3 is the input_type serialized as JSON or null. - // $4 is the output_type serialized as JSON or null. - TemplateQuery insert_execution_type = 55; - - // Inserts a context type into the Type table. It has 1 parameter. - // $0 is the type name - // $1 is the version - // $2 is the description - TemplateQuery insert_context_type = 58; - - // Queries types by a list of type ids. It has 2 parameter. - // $0 is the type_ids - // $1 is the is_artifact_type - TemplateQuery select_types_by_id = 128; - - // Queries types by a list of external ids. - // It has 2 parameters. - // $0 is the external_ids - // $1 is the type_kind - TemplateQuery select_types_by_external_ids = 134; - - // Queries a type by its type id. It has 2 parameters. - // $0 is the type id - // $1 is the is_artifact_type - TemplateQuery select_type_by_id = 6; - - // Queries a type by its type name. It has 2 parameters. - // $0 is the type name - // $1 is the type_kind - TemplateQuery select_type_by_name = 20; - - // Queries a type by its type name and version. It has 3 parameters. - // $0 is the type name - // $1 is the type version - // $2 is the type_kind - TemplateQuery select_type_by_name_and_version = 111; - - // Queries types by a list of type names. - // It has 2 parameters. - // $0 is the type names - // $1 is the type kind - TemplateQuery select_types_by_names = 136; - - // Queries types by a list of type name and version pairs. - // It has 2 parameters. - // $0 is the type name and version pairs - // $1 is the type kind - TemplateQuery select_types_by_names_and_versions = 137; - - // Queries for all type instances. It has 1 parameter. - // $0 is the is_artifact_type - TemplateQuery select_all_types = 57; - - // Updates a type in the Type table. It has 2 parameters. - // $0 is the existing type id - // $1 is the external_id of the Type - TemplateQuery update_type = 138; - - // Drops the ParentType table. - TemplateQuery drop_parent_type_table = 99; - - // Creates the ParentType table. - TemplateQuery create_parent_type_table = 100; - - // Checks the existence of the ParentType table. - TemplateQuery check_parent_type_table = 101; - - // Inserts a parent type into the ParentType table. It has 2 parameters: - // $0 is the type_id - // $1 is the parent_type_id - TemplateQuery insert_parent_type = 109; - - // Queries parent types from the ParentType table by type_id. - // It has 1 parameter. - // $0 is the type_id - TemplateQuery select_parent_type_by_type_id = 110; - - // Drops the TypeProperty table. - TemplateQuery drop_type_property_table = 7; - - // Creates the TypeProperty table. - TemplateQuery create_type_property_table = 8; - - // Checks the existence of the TypeProperty table. - TemplateQuery check_type_property_table = 45; - - // Inserts a property of a type into the TypeProperty table. It has 3 - // parameters. - // $0 is the type_id - // $1 is the name of the property - // $2 is the data_type of the property - TemplateQuery insert_type_property = 9; - - // Queries properties of a type from the TypeProperty table by the type_id - // Returns a list of properties (name, data_type). It has 1 parameter. - // $0 is the type_id - TemplateQuery select_property_by_type_id = 10; - - // Queries the last inserted id. - TemplateQuery select_last_insert_id = 11; - - // Drops the Artifact table. - TemplateQuery drop_artifact_table = 12; - - // Creates the Artifact table. - TemplateQuery create_artifact_table = 13; - - // Checks the existence of the Artifact table. - TemplateQuery check_artifact_table = 46; - - // Inserts an artifact into the Artifact table. It has 5 parameters. - // $0 is the type_id - // $1 is the uri of the Artifact - // $2 is the name of the Artifact - // $3 is the create_time_since_epoch of the Artifact - // $4 is the last_update_time_since_epoch of the Artifact - TemplateQuery insert_artifact = 14; - - // Queries an artifact from the Artifact table by its id. It has 1 parameter. - // $0 is the artifact_id - TemplateQuery select_artifact_by_id = 15; - - // Queries an artifact from the Artifact table by its name and type id. - // It has 2 parameter. - // $0 is the type_id - // $1 is the name of the Artifact - TemplateQuery select_artifact_by_type_id_and_name = 94; - - // Queries an artifact from the Artifact table by its type_id. It has 1 - // parameter. - // $0 is the artifact_type_id - TemplateQuery select_artifacts_by_type_id = 52; - - // Queries an artifact from the Artifact table by its uri. It has 1 parameter. - // $0 is the uri - TemplateQuery select_artifacts_by_uri = 56; - - // Queries artifacts from the Artifact table by - // external_ids. It has 1 parameter. $0 is the external_ids - TemplateQuery select_artifacts_by_external_ids = 130; - - // Updates an artifact in the Artifact table. It has 4 parameters. - // $0 is the existing artifact id - // $1 is the type_id - // $2 is the uri of the Artifact - // $3 is the last_update_time_since_epoch of the Artifact - TemplateQuery update_artifact = 21; - - // Drops the ArtifactProperty table. - TemplateQuery drop_artifact_property_table = 16; - - // Creates the ArtifactProperty table. - TemplateQuery create_artifact_property_table = 17; - - // Checks the existence of the ArtifactProperty table. - TemplateQuery check_artifact_property_table = 47; - - // Insert a property of an artifact from the ArtifactProperty table. It has 5 - // parameters. - // $0 is the property data type - // $1 is the artifact_id - // $2 is the name of the artifact property - // $3 is the flag to indicate whether it is a custom property - // $4 is the value of the property - TemplateQuery insert_artifact_property = 18; - - // Queries properties of an artifact from the ArtifactProperty table by the - // artifact id. It has 1 parameter. - // $0 is the artifact_id - TemplateQuery select_artifact_property_by_artifact_id = 19; - - // Updates a property of an artifact in the ArtifactProperty table. It has 4 - // parameters. - // $0 is the property data type - // $1 is the value of the property - // $2 is the artifact_id - // $3 is the name of the artifact property - TemplateQuery update_artifact_property = 22; - - // Deletes a property of an artifact. It has 2 parameters. - // $0 is the artifact_id - // $1 is the name of the artifact property - TemplateQuery delete_artifact_property = 23; - - // Drops the Execution table. - TemplateQuery drop_execution_table = 24; - - // Creates the Execution table. - TemplateQuery create_execution_table = 25; - - // Checks the existence of the Execution table. - TemplateQuery check_execution_table = 48; - - // Inserts an execution into the Execution table. It has 4 parameter. - // $0 is the type_id - // $1 is the name of the execution - // $2 is the create_time_since_epoch of the execution - // $3 is the last_update_time_since_epoch of the execution - TemplateQuery insert_execution = 28; - - // Queries an execution from the Execution table by its id. It has 1 - // parameter. - // $0 is the execution_id - TemplateQuery select_execution_by_id = 29; - - // Queries an execution from the Execution table by its name and type id. - // It has 2 parameters. - // $0 is the type_id - // $1 is the name - TemplateQuery select_execution_by_type_id_and_name = 95; - - // Queries an execution from the Execution table by its type_id. It has 1 - // parameter. - // $0 is the execution_type_id - TemplateQuery select_executions_by_type_id = 53; - - // Queries executions from the Execution table by external_ids. - // It has 1 parameter. - // $0 is the external_ids - TemplateQuery select_executions_by_external_ids = 132; - - // Updates an execution in the Execution table. It has 3 parameters. - // $0 is the existing execution id - // $1 is the type_id - // $2 is the last_update_time_since_epoch of the execution - TemplateQuery update_execution = 34; - - // Drops the ExecutionProperty table. - TemplateQuery drop_execution_property_table = 26; - - // Creates the ExecutionProperty table. - TemplateQuery create_execution_property_table = 27; - - // Checks the existence of the ExecutionProperty table. - TemplateQuery check_execution_property_table = 49; - - // Insert a property of an execution from the ExecutionProperty table. It has - // 5 parameters. - // $0 is the property data type - // $1 is the execution_id - // $2 is the name of the execution property - // $3 is the flag to indicate whether it is a custom property - // $4 is the value of the property - TemplateQuery insert_execution_property = 30; - - // Queries properties of an execution from the ExecutionProperty table by the - // execution id. It has 1 parameter. - // $0 is the execution_id - TemplateQuery select_execution_property_by_execution_id = 31; - - // Updates a property of an execution in the ExecutionProperty table. It has 4 - // parameters. - // $0 is the property data type - // $1 is the value of the property - // $2 is the execution_id - // $3 is the name of the execution property - TemplateQuery update_execution_property = 32; - - // Deletes a property of an execution. It has 2 parameters. - // $0 is the execution_id - // $1 is the name of the execution property - TemplateQuery delete_execution_property = 33; - - // Drops the Context table. - TemplateQuery drop_context_table = 67; - - // Creates the Context table. - TemplateQuery create_context_table = 68; - - // Checks the existence of the Context table. - TemplateQuery check_context_table = 69; - - // Inserts a context into the Context table. It has 4 parameters. - // $0 is the type_id - // $1 is the name of the Context - // $2 is the create_time_since_epoch of the Context - // $3 is the last_update_time_since_epoch of the Context - TemplateQuery insert_context = 70; - - // Queries a context from the Context table by its id. It has 1 parameter. - // $0 is the context_id - TemplateQuery select_context_by_id = 71; - - // Queries a context from the Context table by its type_id. It has 1 - // parameter. - // $0 is the context_type_id - TemplateQuery select_contexts_by_type_id = 72; - - // Queries a context from the Context table by its type_id and name. It has 2 - // parameters. - // $0 is the context_type_id - // $1 is the context_name - TemplateQuery select_context_by_type_id_and_name = 93; - - // Queries contexts from the Context table by external_ids. - // It has 1 parameter. - // $0 is the external_ids - TemplateQuery select_contexts_by_external_ids = 133; - - // Updates a context in the Context table. It has 4 parameters. - // $0 is the existing context id - // $1 is the type_id - // $2 is the name of the Context - // $3 is the last_update_time_since_epoch of the Context - TemplateQuery update_context = 73; - - // Drops the ContextProperty table. - TemplateQuery drop_context_property_table = 74; - - // Creates the ContextProperty table. - TemplateQuery create_context_property_table = 75; - - // Checks the existence of the ContextProperty table. - TemplateQuery check_context_property_table = 76; - - // Insert a property of a context from the ContextProperty table. It has 5 - // parameters. - // $0 is the property data type - // $1 is the context_id - // $2 is the name of the context property - // $3 is the flag to indicate whether it is a custom property - // $4 is the value of the property - TemplateQuery insert_context_property = 77; - - // Queries properties of a context from the ContextProperty table by the - // context id. It has 1 parameter. - // $0 is the context_id - TemplateQuery select_context_property_by_context_id = 78; - - // Updates a property of a context in the ContextProperty table. It has 4 - // parameters. - // $0 is the property data type - // $1 is the value of the property - // $2 is the context_id - // $3 is the name of the context property - TemplateQuery update_context_property = 79; - - // Deletes a property of a context. It has 2 parameters. - // $0 is the context_id - // $1 is the name of the context property - TemplateQuery delete_context_property = 80; - - // Drops the ParentContext table. - TemplateQuery drop_parent_context_table = 102; - - // Creates the ParentContext table. - TemplateQuery create_parent_context_table = 103; - - // Checks the existence of the ParentContext table. - TemplateQuery check_parent_context_table = 104; - - // Inserts a parent context into the ParentContext table. It has 2 parameters: - // $0 is the context_id - // $1 is the parent_context_id - TemplateQuery insert_parent_context = 106; - - // Queries parent contexts from the ParentContext table by context_id. - // It has 1 parameter. - // $0 is the context_id - TemplateQuery select_parent_context_by_context_id = 107; - - // Queries parent contexts from the ParentContext table by parent_context_id. - // It has 1 parameter. - // $0 is the parent_context_id - TemplateQuery select_parent_context_by_parent_context_id = 108; - - // Queries parent contexts from the ParentContext table by context_ids. - // It has 1 parameter. - // $0 is the context_ids - TemplateQuery select_parent_contexts_by_context_ids = 139; - - // Queries parent contexts from the ParentContext table by parent_context_ids. - // It has 1 parameter. - // $0 is the parent_context_ids - TemplateQuery select_parent_contexts_by_parent_context_ids = 140; - - // Drops the Event table. - TemplateQuery drop_event_table = 35; - - // Creates the Event table. - TemplateQuery create_event_table = 36; - - // Checks the existence of the Event table. - TemplateQuery check_event_table = 50; - - // Inserts an event into the Event table. It has 4 parameters. - // $0 is the artifact_id - // $1 is the execution_id - // $2 is the event type - // $3 is the event time - TemplateQuery insert_event = 37; - - // Queries events from the Event table by a collection of artifact ids. It has - // 1 parameter. - // $0 is the collection string of artifact ids joined by ", ". - TemplateQuery select_event_by_artifact_ids = 96; - - // Queries events from the Event table by a collection of execution ids. It - // has 1 parameter. - // $0 is the collection string of execution ids joined by ", ". - TemplateQuery select_event_by_execution_ids = 97; - - // Drops the EventPath table. - TemplateQuery drop_event_path_table = 40; - - // Creates the EventPath table. - TemplateQuery create_event_path_table = 41; - - // Checks the existence of the EventPath table. - TemplateQuery check_event_path_table = 51; - - // Inserts a path into the EventPath table. It has 4 parameters - // $0 is the event_id - // $1 is the step value case, either index or key - // $2 is the is_index_step indicates the step value case - // $3 is the value of the step - TemplateQuery insert_event_path = 42; - - // Queries paths from the EventPath table by a collection of event ids. It has - // 1 parameter. - // $0 is the collection string of event ids joined by ", ". - TemplateQuery select_event_path_by_event_ids = 98; - - // Drops the Association table. - TemplateQuery drop_association_table = 81; - - // Creates the Association table. - TemplateQuery create_association_table = 82; - - // Checks the existence of the Association table. - TemplateQuery check_association_table = 83; - - // Inserts an association into the Association table. It has 2 parameters. - // $0 is the context_id - // $1 is the execution_id - TemplateQuery insert_association = 84; - - // Queries association from the Association table by its context id. - // It has 1 parameter. - // $0 is the context_id - TemplateQuery select_association_by_context_id = 85; - - reserved 86; - - // Queries associations from the Association table by execution ids. - // It has 1 parameter. - // $0 are the execution_ids. - TemplateQuery select_associations_by_execution_ids = 142; - - // Drops the Attribution table. - TemplateQuery drop_attribution_table = 87; - - // Creates the Attribution table. - TemplateQuery create_attribution_table = 88; - - // Checks the existence of the Attribution table. - TemplateQuery check_attribution_table = 89; - - // Inserts an attribution into the Attribution table. It has 2 parameters. - // $0 is the context_id - // $1 is the artifact_id - TemplateQuery insert_attribution = 90; - - // Queries attribution from the Attribution table by its context id. - // It has 1 parameter. - // $0 is the context_id - TemplateQuery select_attribution_by_context_id = 91; - - reserved 92; - - // Queries attributions from the Attribution table by artifact ids. - // It has 1 parameter. - // $0 are the artifact_ids. - TemplateQuery select_attributions_by_artifact_ids = 143; - - // Drops the MLMDEnv table. - TemplateQuery drop_mlmd_env_table = 60; - - // Creates the MLMDEnv table. - TemplateQuery create_mlmd_env_table = 61; - - // Below is a list of fields required for metadata source migrations when - // the library being used having different versions from a pre-exist database. - - // The version of the current query config. Increase the version by 1 in any - // CL that includes physical schema changes and provides a migration function - // that uses a list migration queries. The database stores it to indicate the - // current database version. When metadata source creates, it compares the - // given `schema_version` in query config with the `schema_version` stored in - // the database, and migrate the database if needed. - int64 schema_version = 59; - - // Checks the MLMDEnv table and query the schema version. - // At MLMD release v0.13.2, by default it is v0. - TemplateQuery check_mlmd_env_table = 63; - - // This query returns an int 0 or int 1 to indicate whether mlmdenv table - // and the corresponding schema exist. In contrast, check_mlmd_env_table - // will return the schema_version value directly, assuming mlmdenv table - // exists. The reason for this query is that PostgreSQL will abort transaction - // if a query inside that transaction fails, while other DB types do not - // abort the transaction. This query serves single purpose to check whether - // mlmdenv table exists, while check_mlmd_env_table serves two goals: table - // schema checking and query for MLMD schema version. - TemplateQuery check_mlmd_env_table_existence = 141; - - // Insert schema_version. - // $0 is the schema_version - TemplateQuery insert_schema_version = 66; - - // Update schema_version - // $0 is the schema_version - TemplateQuery update_schema_version = 64; - - // Check the database is a valid database produced by 0.13.2 MLMD release. - // The schema version and migration are introduced after that release. - TemplateQuery check_tables_in_v0_13_2 = 65; - - // A list of secondary indices to be applied on the current schema. This is - // intended for indices that cover multiple columns or which cannot be - // created as part of table DDL statements. - repeated TemplateQuery secondary_indices = 105; - - reserved 38, 39, 43; - - message DbVerification { - // Total number of MLMD tables. - int32 total_num_tables = 1; - // Total number of MLMD indexes. - int32 total_num_indexes = 2; - } - - // A migration scheme that is used by a migration function to transit a - // database at a schema_version to schema_version + 1. - // DDL is often metadata source specific, if provided, each metadata source - // should have its own setting. - message MigrationScheme { - // Sequence of queries to increase the schema version by 1. - repeated TemplateQuery upgrade_queries = 1; - - // Sequence of queries to decrease the schema version by 1. - repeated TemplateQuery downgrade_queries = 3; - - // For test purposes, it defines the setup query and post condition - // invariants of a migration scheme. - message VerificationScheme { - // This optional field defines the additional details of recreating: - // a) the schema of previous version, as the DDL queries will not be - // available in newer library versions. - // b) and/or the records of related tables which have schema changes. - // Note the setup queries is used in a sequence along with other migration - // schemes of previous version in order to test upgrading from all - // known previous versions to the library version. - repeated TemplateQuery previous_version_setup_queries = 1; - - // This optional field defines the verification queries, each of which - // returns only True/False in the select to assert the state transition - // invariant is the same, e.g., - // * conditions on number of rows - // * conditions on data model entities (e.g., type, artifact, property). - repeated TemplateQuery post_migration_verification_queries = 2; - } - - // Details of verifying the correctness of upgrade_queries. - VerificationScheme upgrade_verification = 2; - - // Details of verifying the correctness of downgrade_queries. - VerificationScheme downgrade_verification = 4; - - // Verification of the DB schema in this version. - DbVerification db_verification = 5; - } - - // Each metadata source should provides migration schemes, each of which - // defines the schema change details for a particular `schema_version` (sv_i). - // When a migration procedure wants to upgrade to sv_i, it looks for the - // MigrationScheme with sv_i as map key. - map migration_schemes = 62; - - // Deletes contexts by id. - // $0 are the context ids. - TemplateQuery delete_contexts_by_id = 112; - - // Deletes contexts properties by contexts ids. - // $0 are the context ids. - TemplateQuery delete_contexts_properties_by_contexts_id = 113; - - // Delete parent contexts by parent context ids. - // $0 are the parent context ids. - TemplateQuery delete_parent_contexts_by_parent_ids = 114; - - // Delete parent contexts by child context ids. - // $0 are the child context ids. - TemplateQuery delete_parent_contexts_by_child_ids = 115; - - // Delete parent contexts by parent context ids. - // $0 is the parent context id. - // $1 are the child context ids. - TemplateQuery delete_parent_contexts_by_parent_id_and_child_ids = 131; - - // Deletes artifacts by id. - // $0 are the artifact ids. - TemplateQuery delete_artifacts_by_id = 116; - - // Deletes artifacts properties by artifacts ids. - // $0 are the artifact ids. - TemplateQuery delete_artifacts_properties_by_artifacts_id = 117; - - // Deletes executions by id. - // $0 are the execution ids. - TemplateQuery delete_executions_by_id = 118; - - // Deletes executions properties by executions ids. - // $0 are the execution ids. - TemplateQuery delete_executions_properties_by_executions_id = 119; - - // Delete events by artifact ids. - // $0 are the artifact ids. - TemplateQuery delete_events_by_artifacts_id = 120; - - // Delete events by execution ids. - // $0 are the execution ids. - TemplateQuery delete_events_by_executions_id = 121; - - // Delete associations by context ids. - // $0 are the context ids. - TemplateQuery delete_associations_by_contexts_id = 122; - - // Delete associations by execution ids. - // $0 are the context ids. - TemplateQuery delete_associations_by_executions_id = 123; - - // Delete attributions by context ids. - // $0 are the context ids. - TemplateQuery delete_attributions_by_contexts_id = 124; - - // Delete attributions by artifact ids. - // $0 are the artifact ids. - TemplateQuery delete_attributions_by_artifacts_id = 125; - - // Delete event paths. This query cleans up event paths where - // the events do not exist. - TemplateQuery delete_event_paths = 126; - - // Delete a parent type from the ParentType table. It has 2 parameters: - // $0 is the type_id - // $1 is the parent_type_id - TemplateQuery delete_parent_type = 127; - - // Queries properties of a list of types from the TypeProperty table by - // `type_ids`. - // Returns a list of properties(type_id, name, data_type).It has 1 parameter: - // $0 is the type_ids - TemplateQuery select_properties_by_type_id = 129; - - // Allows different MetadataSourceTypes to configure its own options when - // creating MetadataAccessObject. - google.protobuf.Any metadata_source_type_specific_options = 135; -} - - -// A payload that can be optionally attached to absl::Status messages to -// indicate failure specific information like error codes for MySQL based -// backends. -message MySQLSourceErrorInfo { - // Error code for the error. - int64 mysql_error_code = 1; -} From 270521ddcc28447ac77799c5e8590aca4d626f45 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 27 Oct 2023 18:13:23 +0200 Subject: [PATCH 085/254] Skip pr checks when changing files not affecting the build (#106) --- .github/workflows/build-image-main.yml | 3 ++- .github/workflows/build-image-pr.yml | 11 ++++++++++- .github/workflows/build.yml | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-image-main.yml b/.github/workflows/build-image-main.yml index 02bb17f2..dcf44369 100644 --- a/.github/workflows/build-image-main.yml +++ b/.github/workflows/build-image-main.yml @@ -2,7 +2,8 @@ name: Main container image build and tag on: push: - branches: [ 'main' ] + branches: + - 'main' env: QUAY_ORG: opendatahub diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index 67342ce3..7032c826 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -2,7 +2,16 @@ name: Test container image build on: pull_request_target: - branches: [ '*' ] + branches: + - '*' + paths-ignore: + - 'LICENSE*' + - '**.gitignore' + - '**.md' + - '**.txt' + - '.github/ISSUE_TEMPLATE/**' + - '.github/dependabot.yml' + - 'docs/**' env: QUAY_IMG_REPO: model-registry diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 88729661..5039e223 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,9 +2,21 @@ name: Build on: push: - branches: [ 'main' ] + branches: + - 'main' pull_request: - branches: [ '*' ] + branches: + - '*' + paths-ignore: + - 'LICENSE*' + - 'DOCKERFILE*' + - '**.gitignore' + - '**.md' + - '**.txt' + - '.github/ISSUE_TEMPLATE/**' + - '.github/dependabot.yml' + - 'docs/**' + - 'scripts/**' jobs: build: From a309537e8b9db0fe4938d978a1b4fb9298974fd7 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Mon, 30 Oct 2023 08:52:43 +0100 Subject: [PATCH 086/254] Improve core layer testing (#85) * Improve core layer testing * Treat ids as string on service layer * Moved testutils inside internal package * Adapt test to name prefix implementation --- Makefile | 4 + internal/core/api.go | 18 +- internal/core/core.go | 144 ++- internal/core/core_test.go | 1204 ++++++++++++++++++-- internal/core/mapper/mlmd_mapper.go | 78 +- internal/testutils/test_container_utils.go | 106 ++ test/bdd/mr_service_features_test.go | 26 +- 7 files changed, 1384 insertions(+), 196 deletions(-) create mode 100644 internal/testutils/test_container_utils.go diff --git a/Makefile b/Makefile index 7f7b599d..e205def1 100644 --- a/Makefile +++ b/Makefile @@ -167,6 +167,10 @@ test: gen test-nocache: gen go test ./internal/... -count=1 +.PHONY: test-cover +test-cover: gen + go test ./internal/... -cover -count=1 + .PHONY: run/migrate run/migrate: gen go run main.go migrate --logtostderr=true -m config/metadata-library diff --git a/internal/core/api.go b/internal/core/api.go index 1dd29f1f..20bff21d 100644 --- a/internal/core/api.go +++ b/internal/core/api.go @@ -19,7 +19,7 @@ type ModelRegistryApi interface { // approach used by MLMD gRPC api. If Id is provided update the entity otherwise create a new one. UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) - GetRegisteredModelById(id *BaseResourceId) (*openapi.RegisteredModel, error) + GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) GetRegisteredModels(listOptions ListOptions) (*openapi.RegisteredModelList, error) @@ -27,19 +27,19 @@ type ModelRegistryApi interface { // Create a new Model Version // or update a Model Version associated to a specific RegisteredModel identified by parentResourceId parameter - UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *BaseResourceId) (*openapi.ModelVersion, error) + UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *string) (*openapi.ModelVersion, error) - GetModelVersionById(id *BaseResourceId) (*openapi.ModelVersion, error) - GetModelVersionByParams(versionName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelVersion, error) - GetModelVersions(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelVersionList, error) + GetModelVersionById(id string) (*openapi.ModelVersion, error) + GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) + GetModelVersions(listOptions ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) // MODEL ARTIFACT // Create a new Artifact // or update an Artifact associated to a specific ModelVersion identified by parentResourceId parameter - UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *BaseResourceId) (*openapi.ModelArtifact, error) + UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *string) (*openapi.ModelArtifact, error) - GetModelArtifactById(id *BaseResourceId) (*openapi.ModelArtifact, error) - GetModelArtifactByParams(artifactName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelArtifact, error) - GetModelArtifacts(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelArtifactList, error) + GetModelArtifactById(id string) (*openapi.ModelArtifact, error) + GetModelArtifactByParams(artifactName *string, parentResourceId *string, externalId *string) (*openapi.ModelArtifact, error) + GetModelArtifacts(listOptions ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) } diff --git a/internal/core/core.go b/internal/core/core.go index 0453d4b2..386c9e94 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "log" - "strconv" "github.com/opendatahub-io/model-registry/internal/core/mapper" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" @@ -80,7 +79,11 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err // REGISTERED MODELS func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) { - log.Printf("Creating or updating registered model for %s", *registeredModel.Name) + if registeredModel.Id == nil { + log.Printf("Creating registered model for %s", *registeredModel.Name) + } else { + log.Printf("Updating registered model %s for %s", *registeredModel.Id, *registeredModel.Name) + } modelCtx, err := serv.mapper.MapFromRegisteredModel(registeredModel) if err != nil { @@ -96,8 +99,8 @@ func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi return nil, err } - modelId := &modelCtxResp.ContextIds[0] - model, err := serv.GetRegisteredModelById((*BaseResourceId)(modelId)) + idAsString := mapper.IdToString(modelCtxResp.ContextIds[0]) + model, err := serv.GetRegisteredModelById(*idAsString) if err != nil { return nil, err } @@ -105,18 +108,23 @@ func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi return model, nil } -func (serv *modelRegistryService) GetRegisteredModelById(id *BaseResourceId) (*openapi.RegisteredModel, error) { - log.Printf("Getting registered model %d", *id) +func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) { + log.Printf("Getting registered model %s", id) + + idAsInt, err := mapper.IdToInt64(id) + if err != nil { + return nil, err + } getByIdResp, err := serv.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ - ContextIds: []int64{int64(*id)}, + ContextIds: []int64{int64(*idAsInt)}, }) if err != nil { return nil, err } if len(getByIdResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple registered models found for id %d", *id) + return nil, fmt.Errorf("multiple registered models found for id %s", id) } regModel, err := serv.mapper.MapToRegisteredModel(getByIdResp.Contexts[0]) @@ -191,10 +199,20 @@ func (serv *modelRegistryService) GetRegisteredModels(listOptions ListOptions) ( // MODEL VERSIONS -func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *BaseResourceId) (*openapi.ModelVersion, error) { - registeredModel, err := serv.GetRegisteredModelById(parentResourceId) +func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *string) (*openapi.ModelVersion, error) { + if modelVersion.Id == nil { + log.Printf("Creating model version") + } else { + log.Printf("Updating model version %s", *modelVersion.Id) + } + + if parentResourceId == nil { + return nil, fmt.Errorf("missing registered model id, cannot create model version without registered model") + } + + registeredModel, err := serv.GetRegisteredModelById(*parentResourceId) if err != nil { - return nil, fmt.Errorf("not a valid registered model id: %d", *parentResourceId) + return nil, fmt.Errorf("not a valid registered model id: %s", *parentResourceId) } registeredModelIdCtxID, err := mapper.IdToInt64(*registeredModel.Id) if err != nil { @@ -216,17 +234,20 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model } modelId := &modelCtxResp.ContextIds[0] - _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ - ParentContexts: []*proto.ParentContext{{ - ChildId: modelId, - ParentId: registeredModelIdCtxID}}, - TransactionOptions: &proto.TransactionOptions{}, - }) - if err != nil { - return nil, err + if modelVersion.Id == nil { + _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ + ParentContexts: []*proto.ParentContext{{ + ChildId: modelId, + ParentId: registeredModelIdCtxID}}, + TransactionOptions: &proto.TransactionOptions{}, + }) + if err != nil { + return nil, err + } } - model, err := serv.GetModelVersionById((*BaseResourceId)(modelId)) + idAsString := mapper.IdToString(*modelId) + model, err := serv.GetModelVersionById(*idAsString) if err != nil { return nil, err } @@ -234,16 +255,21 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model return model, nil } -func (serv *modelRegistryService) GetModelVersionById(id *BaseResourceId) (*openapi.ModelVersion, error) { +func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.ModelVersion, error) { + idAsInt, err := mapper.IdToInt64(id) + if err != nil { + return nil, err + } + getByIdResp, err := serv.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ - ContextIds: []int64{int64(*id)}, + ContextIds: []int64{int64(*idAsInt)}, }) if err != nil { return nil, err } if len(getByIdResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple model versions found for id %d", *id) + return nil, fmt.Errorf("multiple model versions found for id %s", id) } modelVer, err := serv.mapper.MapToModelVersion(getByIdResp.Contexts[0]) @@ -254,10 +280,14 @@ func (serv *modelRegistryService) GetModelVersionById(id *BaseResourceId) (*open return modelVer, nil } -func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelVersion, error) { +func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) { filterQuery := "" if versionName != nil && parentResourceId != nil { - filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned((*int64)(parentResourceId), *versionName)) + idAsInt, err := mapper.IdToInt64(*parentResourceId) + if err != nil { + return nil, err + } + filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned(idAsInt, *versionName)) } else if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) } @@ -273,7 +303,7 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p } if len(getByParamsResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple registered models found for versionName=%v, parentResourceId=%v, externalId=%v", zeroIfNil(versionName), zeroIfNil(parentResourceId), zeroIfNil(externalId)) + return nil, fmt.Errorf("multiple model versions found for versionName=%v, parentResourceId=%v, externalId=%v", zeroIfNil(versionName), zeroIfNil(parentResourceId), zeroIfNil(externalId)) } modelVer, err := serv.mapper.MapToModelVersion(getByParamsResp.Contexts[0]) @@ -283,14 +313,14 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p return modelVer, nil } -func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelVersionList, error) { +func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) { listOperationOptions, err := BuildListOperationOptions(listOptions) if err != nil { return nil, err } if parentResourceId != nil { - queryParentCtxId := fmt.Sprintf("parent_contexts_a.type = %d", *parentResourceId) + queryParentCtxId := fmt.Sprintf("parent_contexts_a.id = %s", *parentResourceId) listOperationOptions.FilterQuery = &queryParentCtxId } @@ -322,8 +352,18 @@ func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, pare // MODEL ARTIFACTS -func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *BaseResourceId) (*openapi.ModelArtifact, error) { - artifact := serv.mapper.MapFromModelArtifact(*modelArtifact, (*int64)(parentResourceId)) +func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *string) (*openapi.ModelArtifact, error) { + if modelArtifact.Id == nil { + log.Printf("Creating model artifact") + } else { + log.Printf("Updating model artifact %s", *modelArtifact.Id) + } + + idAsInt, err := mapper.IdToInt64(*parentResourceId) + if err != nil { + return nil, err + } + artifact := serv.mapper.MapFromModelArtifact(*modelArtifact, idAsInt) artifactsResp, err := serv.mlmdClient.PutArtifacts(context.Background(), &proto.PutArtifactsRequest{ Artifacts: []*proto.Artifact{artifact}, @@ -331,16 +371,17 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod if err != nil { return nil, err } - idString := strconv.FormatInt(artifactsResp.ArtifactIds[0], 10) - modelArtifact.Id = &idString // add explicit association between artifacts and model version - if parentResourceId != nil { - modelVersionIdCtx := int64(*parentResourceId) + if parentResourceId != nil && modelArtifact.Id == nil { + modelVersionIdCtx, err := mapper.IdToInt64(*parentResourceId) + if err != nil { + return nil, err + } attributions := []*proto.Attribution{} for _, a := range artifactsResp.ArtifactIds { attributions = append(attributions, &proto.Attribution{ - ContextId: &modelVersionIdCtx, + ContextId: modelVersionIdCtx, ArtifactId: &a, }) } @@ -353,12 +394,22 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } } - return modelArtifact, nil + idAsString := mapper.IdToString(artifactsResp.ArtifactIds[0]) + mapped, err := serv.GetModelArtifactById(*idAsString) + if err != nil { + return nil, err + } + return mapped, nil } -func (serv *modelRegistryService) GetModelArtifactById(id *BaseResourceId) (*openapi.ModelArtifact, error) { +func (serv *modelRegistryService) GetModelArtifactById(id string) (*openapi.ModelArtifact, error) { + idAsInt, err := mapper.IdToInt64(id) + if err != nil { + return nil, err + } + artifactsResp, err := serv.mlmdClient.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ - ArtifactIds: []int64{int64(*id)}, + ArtifactIds: []int64{int64(*idAsInt)}, }) if err != nil { return nil, err @@ -372,14 +423,18 @@ func (serv *modelRegistryService) GetModelArtifactById(id *BaseResourceId) (*ope return result, nil } -func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, parentResourceId *BaseResourceId, externalId *string) (*openapi.ModelArtifact, error) { +func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, parentResourceId *string, externalId *string) (*openapi.ModelArtifact, error) { var artifact0 *proto.Artifact filterQuery := "" if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) } else if artifactName != nil && parentResourceId != nil { - filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned((*int64)(parentResourceId), *artifactName)) + idAsInt, err := mapper.IdToInt64(*parentResourceId) + if err != nil { + return nil, err + } + filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned(idAsInt, *artifactName)) } else { return nil, fmt.Errorf("invalid parameters call, supply either (artifactName and parentResourceId), or externalId") } @@ -406,7 +461,7 @@ func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, return result, nil } -func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, parentResourceId *BaseResourceId) (*openapi.ModelArtifactList, error) { +func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) { listOperationOptions, err := BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -415,9 +470,12 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, par var artifacts []*proto.Artifact var nextPageToken *string if parentResourceId != nil { - ctxId := int64(*parentResourceId) + ctxId, err := mapper.IdToInt64(*parentResourceId) + if err != nil { + return nil, err + } artifactsResp, err := serv.mlmdClient.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ - ContextId: &ctxId, + ContextId: ctxId, Options: listOperationOptions, }) if err != nil { diff --git a/internal/core/core_test.go b/internal/core/core_test.go index 47caec73..c912d9d1 100644 --- a/internal/core/core_test.go +++ b/internal/core/core_test.go @@ -3,45 +3,214 @@ package core_test import ( "context" "fmt" - "os" "testing" "github.com/opendatahub-io/model-registry/internal/core" "github.com/opendatahub-io/model-registry/internal/core/mapper" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/internal/testutils" "github.com/stretchr/testify/assert" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" ) -const ( - useProvider = testcontainers.ProviderDefault // or explicit to testcontainers.ProviderPodman if needed - mlmdImage = "gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0" - sqliteFile = "metadata.sqlite.db" - testConfigFolder = "test/config/ml-metadata" +// common utility test variables +var ( + // generic + ascOrderDirection string + descOrderDirection string + // registered models + modelName string + modelExternalId string + owner string + // model version + modelVersionName string + versionExternalId string + author string + // model artifact + artifactName string + artifactExtId string + artifactState string + artifactUri string ) -func TestCreateRegisteredModel(t *testing.T) { - conn, client, teardown := SetupTestContainer(t) +func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { + // initialize test variable before each test + ascOrderDirection = "ASC" + descOrderDirection = "DESC" + modelName = "MyAwesomeModel" + modelExternalId = "org.myawesomemodel" + owner = "owner" + modelVersionName = "v1" + versionExternalId = "org.myawesomemodel@v1" + author = "author1" + artifactName = "Pickle model" + artifactExtId = "org.myawesomemodel@v1:pickle" + artifactState = "LIVE" + artifactUri = "path/to/model/v1" + + conn, client, teardown := testutils.SetupMLMDTestContainer(t) + return assert.New(t), conn, client, teardown +} + +// initialize model registry service and assert no error is thrown +func initModelRegistryService(assertion *assert.Assertions, conn *grpc.ClientConn) core.ModelRegistryApi { + service, err := core.NewModelRegistryService(conn) + assertion.Nilf(err, "error creating core service: %v", err) + return service +} + +// utility function that register a new simple model and return its ID +func registerModel(assertion *assert.Assertions, service core.ModelRegistryApi, overrideModelName *string, overrideExternalId *string) string { + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, + } + + if overrideModelName != nil { + registeredModel.Name = overrideModelName + } + + if overrideExternalId != nil { + registeredModel.ExternalID = overrideExternalId + } + + // test + createdModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + return *createdModel.Id +} + +// utility function that register a new simple model and return its ID +func registerModelVersion( + assertion *assert.Assertions, + service core.ModelRegistryApi, + overrideModelName *string, + overrideExternalId *string, + overrideVersionName *string, + overrideVersionExtId *string, +) string { + registeredModelId := registerModel(assertion, service, overrideModelName, overrideExternalId) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + if overrideVersionName != nil { + modelVersion.Name = overrideVersionName + } + + if overrideVersionExtId != nil { + modelVersion.ExternalID = overrideVersionExtId + } + + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating model version: %v", err) + + return *createdVersion.Id +} + +func TestModelRegistryTypes(t *testing.T) { + assertion, conn, client, teardown := setup(t) defer teardown(t) - // [TEST CASE] + // create mode registry service + _ = initModelRegistryService(assertion, conn) + + // assure the types have been correctly setup at startup + ctx := context.Background() + regModelResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: &core.RegisteredModelTypeName, + }) + assertion.NotNilf(regModelResp.ContextType, "registered model type %s should exists", core.RegisteredModelTypeName) + assertion.Equal(core.RegisteredModelTypeName, *regModelResp.ContextType.Name) + + modelVersionResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: &core.ModelVersionTypeName, + }) + assertion.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", core.ModelVersionTypeName) + assertion.Equal(core.ModelVersionTypeName, *modelVersionResp.ContextType.Name) + + modelArtifactResp, _ := client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + TypeName: &core.ModelArtifactTypeName, + }) + assertion.NotNilf(modelArtifactResp.ArtifactType, "model version type %s should exists", core.ModelArtifactTypeName) + assertion.Equal(core.ModelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) +} + +// REGISTERED MODELS + +func TestCreateRegisteredModel(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) // create mode registry service - service, err := core.NewModelRegistryService(conn) - assert.Nilf(t, err, "error creating core service: %v", err) + service := initModelRegistryService(assertion, conn) - modelName := "PricingModel" - externalId := "myExternalId" - owner := "Myself" + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, + } + + // test + createdModel, err := service.UpsertRegisteredModel(registeredModel) + + // checks + assertion.Nilf(err, "error creating registered model: %v", err) + assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") + + byTypeAndNameResp, err := client.GetContextByTypeAndName(context.Background(), &proto.GetContextByTypeAndNameRequest{ + TypeName: &core.RegisteredModelTypeName, + ContextName: &modelName, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctxId := mapper.IdToString(*byTypeAndNameResp.Context.Id) + assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") + assertion.Equal(modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") + assertion.Equal(modelExternalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") + assertion.Equal(owner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") +} + +func TestUpdateRegisteredModel(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) // register a new model registeredModel := &openapi.RegisteredModel{ Name: &modelName, - ExternalID: &externalId, + ExternalID: &modelExternalId, CustomProperties: &map[string]openapi.MetadataValue{ "owner": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -55,144 +224,965 @@ func TestCreateRegisteredModel(t *testing.T) { createdModel, err := service.UpsertRegisteredModel(registeredModel) // checks - assert.Nilf(t, err, "error creating registered model: %v", err) - assert.NotNilf(t, createdModel.Id, "created registered model should not have nil Id") + assertion.Nilf(err, "error creating registered model: %v", err) + assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") + + // checks created model matches original one except for Id + assertion.Equal(*registeredModel.Name, *createdModel.Name, "returned model name should match the original one") + assertion.Equal(*registeredModel.ExternalID, *createdModel.ExternalID, "returned model external id should match the original one") + assertion.Equal(*registeredModel.CustomProperties, *createdModel.CustomProperties, "returned model custom props should match the original one") byTypeAndNameResp, err := client.GetContextByTypeAndName(context.Background(), &proto.GetContextByTypeAndNameRequest{ TypeName: &core.RegisteredModelTypeName, ContextName: &modelName, }) - assert.Nilf(t, err, "error retrieving context by type and name, not related to the test itself: %v", err) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctxId := mapper.IdToString(*byTypeAndNameResp.Context.Id) - assert.Equal(t, *createdModel.Id, *ctxId, "returned model id should match the mlmd one") - assert.Equal(t, modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") - assert.Equal(t, externalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") - assert.Equal(t, owner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") + assertion.Equal(modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") + assertion.Equal(modelExternalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") + assertion.Equal(owner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assert.Nilf(t, err, "error retrieving all contexts, not related to the test itself: %v", err) - assert.Equal(t, 1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + + // update existing model + newModelExternalId := "newExternalId" + newOwner := "newOwner" + + createdModel.ExternalID = &newModelExternalId + (*createdModel.CustomProperties)["owner"] = openapi.MetadataValue{ + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &newOwner, + }, + } + + // update the model + createdModel, err = service.UpsertRegisteredModel(createdModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + // still one registered model + getAllResp, err = client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + + byTypeAndNameResp, err = client.GetContextByTypeAndName(context.Background(), &proto.GetContextByTypeAndNameRequest{ + TypeName: &core.RegisteredModelTypeName, + ContextName: &modelName, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctxId = mapper.IdToString(*byTypeAndNameResp.Context.Id) + assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") + assertion.Equal(modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") + assertion.Equal(newModelExternalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") + assertion.Equal(newOwner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") } func TestGetRegisteredModelById(t *testing.T) { - conn, _, teardown := SetupTestContainer(t) + assertion, conn, _, teardown := setup(t) defer teardown(t) - // [TEST CASE] - // create mode registry service - service, err := core.NewModelRegistryService(conn) - assert.Nilf(t, err, "error creating core service: %v", err) - - modelName := "PricingModel" - externalId := "mysupermodel" + service := initModelRegistryService(assertion, conn) // register a new model registeredModel := &openapi.RegisteredModel{ Name: &modelName, - ExternalID: &externalId, + ExternalID: &modelExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, } // test createdModel, err := service.UpsertRegisteredModel(registeredModel) // checks - assert.Nilf(t, err, "error creating registered model: %v", err) + assertion.Nilf(err, "error creating registered model: %v", err) - modelId, _ := mapper.IdToInt64(*createdModel.Id) - getModelById, err := service.GetRegisteredModelById((*core.BaseResourceId)(modelId)) - assert.Nilf(t, err, "error getting registered model by id %d: %v", *modelId, err) + getModelById, err := service.GetRegisteredModelById(*createdModel.Id) + assertion.Nilf(err, "error getting registered model by id %s: %v", *createdModel.Id, err) - assert.Equal(t, modelName, *getModelById.Name, "saved model name should match the provided one") - assert.Equal(t, externalId, *getModelById.ExternalID, "saved external id should match the provided one") + // checks created model matches original one except for Id + assertion.Equal(*registeredModel.Name, *getModelById.Name, "saved model name should match the original one") + assertion.Equal(*registeredModel.ExternalID, *getModelById.ExternalID, "saved model external id should match the original one") + assertion.Equal(*registeredModel.CustomProperties, *getModelById.CustomProperties, "saved model custom props should match the original one") } -// ################# -// ##### Utils ##### -// ################# +func TestGetRegisteredModelByParamsName(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) -func clearMetadataSqliteDB(wd string) error { - if err := os.Remove(fmt.Sprintf("%s/%s", wd, sqliteFile)); err != nil { - return fmt.Errorf("expected to clear sqlite file but didn't find: %v", err) + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, } - return nil + + createdModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + byName, err := service.GetRegisteredModelByParams(&modelName, nil) + assertion.Nilf(err, "error getting registered model by name: %v", err) + + assertion.Equalf(*createdModel.Id, *byName.Id, "the returned model id should match the retrieved by name") } -// SetupTestContainer creates a MLMD gRPC test container -// Returns -// - gRPC client connection to the test container -// - ml-metadata client used to double check the database -// - teardown function -func SetupTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { - ctx := context.Background() - wd, err := os.Getwd() - if err != nil { - t.Errorf("error getting working directory: %v", err) +func TestGetRegisteredModelByParamsExternalId(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, + } + + createdModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + byName, err := service.GetRegisteredModelByParams(nil, &modelExternalId) + assertion.Nilf(err, "error getting registered model by external id: %v", err) + + assertion.Equalf(*createdModel.Id, *byName.Id, "the returned model id should match the retrieved by name") +} + +func TestGetRegisteredModelsOrderedById(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + orderBy := "ID" + + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, + } + + _, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + newModelName := "PricingModel2" + newModelExternalId := "myExternalId2" + registeredModel.Name = &newModelName + registeredModel.ExternalID = &newModelExternalId + _, err = service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + newModelName = "PricingModel3" + newModelExternalId = "myExternalId3" + registeredModel.Name = &newModelName + registeredModel.ExternalID = &newModelExternalId + _, err = service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + orderedById, err := service.GetRegisteredModels(core.ListOptions{ + OrderBy: &orderBy, + SortOrder: &ascOrderDirection, + }) + assertion.Nilf(err, "error getting registered models: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + for i := 0; i < int(orderedById.Size)-1; i++ { + assertion.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + } + + orderedById, err = service.GetRegisteredModels(core.ListOptions{ + OrderBy: &orderBy, + SortOrder: &descOrderDirection, + }) + assertion.Nilf(err, "error getting registered models: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + for i := 0; i < int(orderedById.Size)-1; i++ { + assertion.Greater(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + } +} + +func TestGetRegisteredModelsOrderedByLastUpdate(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + orderBy := "LAST_UPDATE_TIME" + + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, + } + + firstModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + newModelName := "PricingModel2" + newModelExternalId := "myExternalId2" + registeredModel.Name = &newModelName + registeredModel.ExternalID = &newModelExternalId + secondModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + newModelName = "PricingModel3" + newModelExternalId = "myExternalId3" + registeredModel.Name = &newModelName + registeredModel.ExternalID = &newModelExternalId + thirdModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + // update second model + secondModel.ExternalID = nil + _, err = service.UpsertRegisteredModel(secondModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + orderedById, err := service.GetRegisteredModels(core.ListOptions{ + OrderBy: &orderBy, + SortOrder: &ascOrderDirection, + }) + assertion.Nilf(err, "error getting registered models: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + assertion.Equal(*firstModel.Id, *orderedById.Items[0].Id) + assertion.Equal(*thirdModel.Id, *orderedById.Items[1].Id) + assertion.Equal(*secondModel.Id, *orderedById.Items[2].Id) + + orderedById, err = service.GetRegisteredModels(core.ListOptions{ + OrderBy: &orderBy, + SortOrder: &descOrderDirection, + }) + assertion.Nilf(err, "error getting registered models: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + assertion.Equal(*secondModel.Id, *orderedById.Items[0].Id) + assertion.Equal(*thirdModel.Id, *orderedById.Items[1].Id) + assertion.Equal(*firstModel.Id, *orderedById.Items[2].Id) +} + +func TestGetRegisteredModelsWithPageSize(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + pageSize := int32(1) + pageSize2 := int32(2) + modelName := "PricingModel1" + modelExternalId := "myExternalId1" + + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, + } + + firstModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + newModelName := "PricingModel2" + newModelExternalId := "myExternalId2" + registeredModel.Name = &newModelName + registeredModel.ExternalID = &newModelExternalId + secondModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + newModelName = "PricingModel3" + newModelExternalId = "myExternalId3" + registeredModel.Name = &newModelName + registeredModel.ExternalID = &newModelExternalId + thirdModel, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + truncatedList, err := service.GetRegisteredModels(core.ListOptions{ + PageSize: &pageSize, + }) + assertion.Nilf(err, "error getting registered models: %v", err) + + assertion.Equal(1, int(truncatedList.Size)) + assertion.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") + assertion.Equal(*firstModel.Id, *truncatedList.Items[0].Id) + + truncatedList, err = service.GetRegisteredModels(core.ListOptions{ + PageSize: &pageSize2, + NextPageToken: &truncatedList.NextPageToken, + }) + assertion.Nilf(err, "error getting registered models: %v", err) + + assertion.Equal(2, int(truncatedList.Size)) + assertion.Equal("", truncatedList.NextPageToken, "next page token should be empty as list item returned") + assertion.Equal(*secondModel.Id, *truncatedList.Items[0].Id) + assertion.Equal(*thirdModel.Id, *truncatedList.Items[1].Id) +} + +// MODEL VERSIONS + +func TestCreateModelVersionWithInvalidRegisteredModelId(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + notExistingRegisteredModelId := "9999" + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdVersion, err := service.UpsertModelVersion(modelVersion, ¬ExistingRegisteredModelId) + assertion.NotNil(err, "model version should fail because registered model id does not exist") + assertion.Equal(fmt.Sprintf("not a valid registered model id: %s", notExistingRegisteredModelId), err.Error()) + assertion.Nil(createdVersion) +} + +func TestCreateModelVersion(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, } - wd = fmt.Sprintf("%s/../../%s", wd, testConfigFolder) - t.Logf("using working directory: %s", wd) - req := testcontainers.ContainerRequest{ - Image: mlmdImage, - ExposedPorts: []string{"8080/tcp"}, - Env: map[string]string{ - "METADATA_STORE_SERVER_CONFIG_FILE": "/tmp/shared/conn_config.pb", + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + + createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + + byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdVersionId, }, - Mounts: testcontainers.ContainerMounts{ - testcontainers.ContainerMount{ - Source: testcontainers.GenericBindMountSource{ - HostPath: wd, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + + assertion.Equal(*createdVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") + assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") + assertion.Equal(versionExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equalf(core.ModelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", core.ModelVersionTypeName) + + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") +} + +func TestUpdateModelVersion(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, }, - Target: "/tmp/shared", }, }, - WaitingFor: wait.ForLog("Server listening on"), } - mlmdgrpc, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ProviderType: useProvider, - ContainerRequest: req, - Started: true, + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + + newExternalId := "org.my_awesome_model@v1" + newScore := 0.95 + + createdVersion.ExternalID = &newExternalId + (*createdVersion.CustomProperties)["score"] = openapi.MetadataValue{ + MetadataDoubleValue: &openapi.MetadataDoubleValue{ + DoubleValue: &newScore, + }, + } + + updatedVersion, err := service.UpsertModelVersion(createdVersion, ®isteredModelId) + assertion.Nilf(err, "error updating new model version for %d: %v", registeredModelId, err) + + updateVersionId, _ := mapper.IdToInt64(*updatedVersion.Id) + assertion.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") + + byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *updateVersionId, + }, }) - if err != nil { - t.Errorf("error setting up mlmd grpc container: %v", err) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + + assertion.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") + assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") + assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + assertion.Equalf(core.ModelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", core.ModelVersionTypeName) + + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + fmt.Printf("%+v", getAllResp.Contexts) + assertion.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") +} + +func TestGetModelVersionById(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, } - mappedHost, err := mlmdgrpc.Host(ctx) - if err != nil { - t.Error(err) + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + + getById, err := service.GetModelVersionById(*createdVersion.Id) + assertion.Nilf(err, "error getting model version with id %d", *createdVersionId) + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdVersionId, + }, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + assertion.Equal(*getById.Id, *mapper.IdToString(*ctx.Id), "returned model version id should match the mlmd context one") + assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getById.Name), *ctx.Name, "saved model name should match the provided one") + assertion.Equal(*getById.ExternalID, *modelVersion.ExternalID, "saved external id should match the provided one") + assertion.Equal(*(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, author, "saved author custom property should match the provided one") +} + +func TestGetModelVersionByParamsName(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, } - mappedPort, err := mlmdgrpc.MappedPort(ctx, "8080") - if err != nil { - t.Error(err) + + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + + getByName, err := service.GetModelVersionByParams(&modelVersionName, ®isteredModelId, nil) + assertion.Nilf(err, "error getting model version by name %d", *createdVersionId) + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdVersionId, + }, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + assertion.Equal(*mapper.IdToString(*ctx.Id), *getByName.Id, "returned model version id should match the mlmd context one") + assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByName.Name), *ctx.Name, "saved model name should match the provided one") + assertion.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") + assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByName.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") +} + +func TestGetModelVersionByParamsExternalId(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, } - mlmdAddr := fmt.Sprintf("%s:%s", mappedHost, mappedPort.Port()) - t.Log("MLMD test container setup at: ", mlmdAddr) - // setup grpc connection - conn, err := grpc.DialContext( - context.Background(), - mlmdAddr, - grpc.WithReturnConnectionError(), - grpc.WithBlock(), - grpc.WithTransportCredentials(insecure.NewCredentials()), - ) - if err != nil { - t.Errorf("error dialing connection to mlmd server %s: %v", mlmdAddr, err) + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + + getByExternalId, err := service.GetModelVersionByParams(nil, nil, modelVersion.ExternalID) + assertion.Nilf(err, "error getting model version by external id %d", *modelVersion.ExternalID) + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdVersionId, + }, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + assertion.Equal(*mapper.IdToString(*ctx.Id), *getByExternalId.Id, "returned model version id should match the mlmd context one") + assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByExternalId.Name), *ctx.Name, "saved model name should match the provided one") + assertion.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") + assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByExternalId.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") +} + +func TestGetModelVersions(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion1 := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + } + + secondModelVersionName := "v2" + secondModelVersionExtId := "org.myawesomemodel@v2" + modelVersion2 := &openapi.ModelVersion{ + Name: &secondModelVersionName, + ExternalID: &secondModelVersionExtId, + } + + thirdModelVersionName := "v3" + thirdModelVersionExtId := "org.myawesomemodel@v3" + modelVersion3 := &openapi.ModelVersion{ + Name: &thirdModelVersionName, + ExternalID: &thirdModelVersionExtId, } - mlmdClient := proto.NewMetadataStoreServiceClient(conn) + createdVersion1, err := service.UpsertModelVersion(modelVersion1, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + createdVersion2, err := service.UpsertModelVersion(modelVersion2, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) - return conn, mlmdClient, func(t *testing.T) { - if err := conn.Close(); err != nil { - t.Error(err) - } - if err := mlmdgrpc.Terminate(ctx); err != nil { - t.Error(err) - } - if err := clearMetadataSqliteDB(wd); err != nil { - t.Error(err) - } + createdVersion3, err := service.UpsertModelVersion(modelVersion3, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + anotherRegModelName := "AnotherModel" + anotherRegModelExtId := "org.another" + anotherRegisteredModelId := registerModel(assertion, service, &anotherRegModelName, &anotherRegModelExtId) + + anotherModelVersionName := "v1.0" + anotherModelVersionExtId := "org.another@v1.0" + modelVersionAnother := &openapi.ModelVersion{ + Name: &anotherModelVersionName, + ExternalID: &anotherModelVersionExtId, } + + _, err = service.UpsertModelVersion(modelVersionAnother, &anotherRegisteredModelId) + assertion.Nilf(err, "error creating new model version for %d", anotherRegisteredModelId) + + createdVersionId1, _ := mapper.IdToInt64(*createdVersion1.Id) + createdVersionId2, _ := mapper.IdToInt64(*createdVersion2.Id) + createdVersionId3, _ := mapper.IdToInt64(*createdVersion3.Id) + + getAll, err := service.GetModelVersions(core.ListOptions{}, nil) + assertion.Nilf(err, "error getting all model versions") + assertion.Equal(int32(4), getAll.Size, "expected four model versions across all registered models") + + getAllByRegModel, err := service.GetModelVersions(core.ListOptions{}, ®isteredModelId) + assertion.Nilf(err, "error getting all model versions") + assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) + + assertion.Equal(*mapper.IdToString(*createdVersionId1), *getAllByRegModel.Items[0].Id) + assertion.Equal(*mapper.IdToString(*createdVersionId2), *getAllByRegModel.Items[1].Id) + assertion.Equal(*mapper.IdToString(*createdVersionId3), *getAllByRegModel.Items[2].Id) + + // order by last update time, expecting last created as first + orderByLastUpdate := "LAST_UPDATE_TIME" + getAllByRegModel, err = service.GetModelVersions(core.ListOptions{ + OrderBy: &orderByLastUpdate, + SortOrder: &descOrderDirection, + }, ®isteredModelId) + assertion.Nilf(err, "error getting all model versions") + assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) + + assertion.Equal(*mapper.IdToString(*createdVersionId1), *getAllByRegModel.Items[2].Id) + assertion.Equal(*mapper.IdToString(*createdVersionId2), *getAllByRegModel.Items[1].Id) + assertion.Equal(*mapper.IdToString(*createdVersionId3), *getAllByRegModel.Items[0].Id) + + // update the second version + newVersionExternalId := "updated.org:v2" + createdVersion2.ExternalID = &newVersionExternalId + createdVersion2, err = service.UpsertModelVersion(createdVersion2, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + + assertion.Equal(newVersionExternalId, *createdVersion2.ExternalID) + + getAllByRegModel, err = service.GetModelVersions(core.ListOptions{ + OrderBy: &orderByLastUpdate, + SortOrder: &descOrderDirection, + }, ®isteredModelId) + assertion.Nilf(err, "error getting all model versions") + assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) + + assertion.Equal(*mapper.IdToString(*createdVersionId1), *getAllByRegModel.Items[2].Id) + assertion.Equal(*mapper.IdToString(*createdVersionId2), *getAllByRegModel.Items[0].Id) + assertion.Equal(*mapper.IdToString(*createdVersionId3), *getAllByRegModel.Items[1].Id) +} + +// MODEL ARTIFACTS + +func TestCreateModelArtifact(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + modelArtifact := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + + state, _ := openapi.NewArtifactStateFromValue(artifactState) + assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") + assertion.Equal(artifactName, *createdArtifact.Name) + assertion.Equal(*state, *createdArtifact.State) + assertion.Equal(artifactUri, *createdArtifact.Uri) + assertion.Equal(author, *(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue) + + createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) + getById, err := client.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ + ArtifactIds: []int64{*createdArtifactId}, + }) + assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + + assertion.Equal(*createdArtifactId, *getById.Artifacts[0].Id) + assertion.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) + assertion.Equal(string(*createdArtifact.State), getById.Artifacts[0].State.String()) + assertion.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) + assertion.Equal(*(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["author"].GetStringValue()) + + modelVersionIdAsInt, _ := mapper.IdToInt64(modelVersionId) + byCtx, _ := client.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ + ContextId: (*int64)(modelVersionIdAsInt), + }) + assertion.Equal(1, len(byCtx.Artifacts)) + assertion.Equal(*createdArtifactId, *byCtx.Artifacts[0].Id) +} + +func TestUpdateModelArtifact(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + modelArtifact := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + + newState := "MARKED_FOR_DELETION" + createdArtifact.State = (*openapi.ArtifactState)(&newState) + updatedArtifact, err := service.UpsertModelArtifact(createdArtifact, &modelVersionId) + assertion.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) + + createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) + updatedArtifactId, _ := mapper.IdToInt64(*updatedArtifact.Id) + assertion.Equal(createdArtifactId, updatedArtifactId) + + getById, err := client.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ + ArtifactIds: []int64{*createdArtifactId}, + }) + assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + + assertion.Equal(*createdArtifactId, *getById.Artifacts[0].Id) + assertion.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) + assertion.Equal(string(newState), getById.Artifacts[0].State.String()) + assertion.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) + assertion.Equal(*(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["author"].GetStringValue()) +} + +func TestGetModelArtifactById(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + modelArtifact := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + + createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) + + getById, err := service.GetModelArtifactById(*createdArtifact.Id) + assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + + state, _ := openapi.NewArtifactStateFromValue(artifactState) + assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") + assertion.Equal(artifactName, *getById.Name) + assertion.Equal(*state, *getById.State) + assertion.Equal(artifactUri, *getById.Uri) + assertion.Equal(author, *(*getById.CustomProperties)["author"].MetadataStringValue.StringValue) + + assertion.Equal(*createdArtifact, *getById, "artifacts returned during creation and on get by id should be equal") +} + +func TestGetModelArtifactByParams(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + modelArtifact := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + ExternalID: &artifactExtId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + + createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) + + state, _ := openapi.NewArtifactStateFromValue(artifactState) + + getByName, err := service.GetModelArtifactByParams(&artifactName, &modelVersionId, nil) + assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + + assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") + assertion.Equal(artifactName, *getByName.Name) + assertion.Equal(artifactExtId, *getByName.ExternalID) + assertion.Equal(*state, *getByName.State) + assertion.Equal(artifactUri, *getByName.Uri) + assertion.Equal(author, *(*getByName.CustomProperties)["author"].MetadataStringValue.StringValue) + + assertion.Equal(*createdArtifact, *getByName, "artifacts returned during creation and on get by name should be equal") + + getByExtId, err := service.GetModelArtifactByParams(nil, nil, &artifactExtId) + assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + + assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") + assertion.Equal(artifactName, *getByExtId.Name) + assertion.Equal(artifactExtId, *getByExtId.ExternalID) + assertion.Equal(*state, *getByExtId.State) + assertion.Equal(artifactUri, *getByExtId.Uri) + assertion.Equal(author, *(*getByExtId.CustomProperties)["author"].MetadataStringValue.StringValue) + + assertion.Equal(*createdArtifact, *getByExtId, "artifacts returned during creation and on get by ext id should be equal") +} + +func TestGetModelArtifacts(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + modelArtifact1 := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + ExternalID: &artifactExtId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + secondArtifactName := "second-name" + secondArtifactExtId := "second-ext-id" + secondArtifactUri := "second-uri" + modelArtifact2 := &openapi.ModelArtifact{ + Name: &secondArtifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &secondArtifactUri, + ExternalID: &secondArtifactExtId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + thirdArtifactName := "third-name" + thirdArtifactExtId := "third-ext-id" + thirdArtifactUri := "third-uri" + modelArtifact3 := &openapi.ModelArtifact{ + Name: &thirdArtifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &thirdArtifactUri, + ExternalID: &thirdArtifactExtId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdArtifact1, err := service.UpsertModelArtifact(modelArtifact1, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + createdArtifact2, err := service.UpsertModelArtifact(modelArtifact2, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + createdArtifact3, err := service.UpsertModelArtifact(modelArtifact3, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + + createdArtifactId1, _ := mapper.IdToInt64(*createdArtifact1.Id) + createdArtifactId2, _ := mapper.IdToInt64(*createdArtifact2.Id) + createdArtifactId3, _ := mapper.IdToInt64(*createdArtifact3.Id) + + getAll, err := service.GetModelArtifacts(core.ListOptions{}, nil) + assertion.Nilf(err, "error getting all model artifacts") + assertion.Equalf(int32(3), getAll.Size, "expected three model artifacts") + + assertion.Equal(*mapper.IdToString(*createdArtifactId1), *getAll.Items[0].Id) + assertion.Equal(*mapper.IdToString(*createdArtifactId2), *getAll.Items[1].Id) + assertion.Equal(*mapper.IdToString(*createdArtifactId3), *getAll.Items[2].Id) + + orderByLastUpdate := "LAST_UPDATE_TIME" + getAllByModelVersion, err := service.GetModelArtifacts(core.ListOptions{ + OrderBy: &orderByLastUpdate, + SortOrder: &descOrderDirection, + }, &modelVersionId) + assertion.Nilf(err, "error getting all model artifacts for %d", modelVersionId) + assertion.Equalf(int32(3), getAllByModelVersion.Size, "expected three model artifacts for model version %d", modelVersionId) + + assertion.Equal(*mapper.IdToString(*createdArtifactId1), *getAllByModelVersion.Items[2].Id) + assertion.Equal(*mapper.IdToString(*createdArtifactId2), *getAllByModelVersion.Items[1].Id) + assertion.Equal(*mapper.IdToString(*createdArtifactId3), *getAllByModelVersion.Items[0].Id) } diff --git a/internal/core/mapper/mlmd_mapper.go b/internal/core/mapper/mlmd_mapper.go index f4d0589a..1d4adbae 100644 --- a/internal/core/mapper/mlmd_mapper.go +++ b/internal/core/mapper/mlmd_mapper.go @@ -98,6 +98,15 @@ func (m *Mapper) MapToProperties(data map[string]openapi.MetadataValue) (map[str return props, nil } +func (m *Mapper) MapToArtifactState(oapiState *openapi.ArtifactState) *proto.Artifact_State { + if oapiState == nil { + return nil + } + + state := (proto.Artifact_State)(proto.Artifact_State_value[string(*oapiState)]) + return &state +} + func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel) (*proto.Context, error) { var idInt *int64 @@ -129,9 +138,20 @@ func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registe if modelVersion.CustomProperties != nil { customProps, _ = m.MapToProperties(*modelVersion.CustomProperties) } + + var idAsInt *int64 + if modelVersion.Id != nil { + var err error + idAsInt, err = IdToInt64(*modelVersion.Id) + if err != nil { + return nil, err + } + } ctx := &proto.Context{ - Name: &fullName, - TypeId: &m.ModelVersionTypeId, + Id: idAsInt, + Name: &fullName, + TypeId: &m.ModelVersionTypeId, + ExternalId: modelVersion.ExternalID, Properties: map[string]*proto.Value{ "model_name": { Value: &proto.Value_StringValue{ @@ -170,10 +190,25 @@ func (m *Mapper) MapFromModelArtifact(modelArtifact openapi.ModelArtifact, model } // build fullName for mlmd storage fullName := PrefixWhenOwned(modelVersionId, artifactName) + + customProps := make(map[string]*proto.Value) + if modelArtifact.CustomProperties != nil { + customProps, _ = m.MapToProperties(*modelArtifact.CustomProperties) + } + + var idAsInt *int64 + if modelArtifact.Id != nil { + idAsInt, _ = IdToInt64(*modelArtifact.Id) + } + return &proto.Artifact{ - TypeId: &m.ModelArtifactTypeId, - Name: &fullName, - Uri: modelArtifact.Uri, + Id: idAsInt, + TypeId: &m.ModelArtifactTypeId, + Name: &fullName, + Uri: modelArtifact.Uri, + ExternalId: modelArtifact.ExternalID, + State: m.MapToArtifactState(modelArtifact.State), + CustomProperties: customProps, } } @@ -236,12 +271,21 @@ func (m *Mapper) MapFromProperties(props map[string]*proto.Value) (map[string]op return data, nil } +func (m *Mapper) MapFromArtifactState(mlmdState *proto.Artifact_State) *openapi.ArtifactState { + if mlmdState == nil { + return nil + } + + state := mlmdState.String() + return (*openapi.ArtifactState)(&state) +} + func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredModel, error) { if ctx.GetTypeId() != m.RegisteredModelTypeId { return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.RegisteredModelTypeId, ctx.GetTypeId()) } - _, err := m.MapFromProperties(ctx.CustomProperties) + customProps, err := m.MapFromProperties(ctx.CustomProperties) if err != nil { return nil, err } @@ -249,9 +293,10 @@ func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredMo idString := strconv.FormatInt(*ctx.Id, 10) model := &openapi.RegisteredModel{ - Id: &idString, - Name: ctx.Name, - ExternalID: ctx.ExternalId, + Id: &idString, + Name: ctx.Name, + ExternalID: ctx.ExternalId, + CustomProperties: &customProps, } return model, nil @@ -276,8 +321,9 @@ func (m *Mapper) MapToModelVersion(ctx *proto.Context) (*openapi.ModelVersion, e name := NameFromOwned(*ctx.Name) modelVersion := &openapi.ModelVersion{ // ModelName: &modelName, - Id: &idString, - Name: &name, + Id: &idString, + Name: &name, + ExternalID: ctx.ExternalId, // Author: &author, CustomProperties: &metadata, } @@ -290,7 +336,7 @@ func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArt return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.ModelArtifactTypeId, artifact.GetTypeId()) } - _, err := m.MapFromProperties(artifact.CustomProperties) + customProps, err := m.MapFromProperties(artifact.CustomProperties) if err != nil { return nil, err } @@ -302,8 +348,12 @@ func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArt name := NameFromOwned(*artifact.Name) modelArtifact := &openapi.ModelArtifact{ - Uri: artifact.Uri, - Name: &name, + Id: IdToString(*artifact.Id), + Uri: artifact.Uri, + Name: &name, + ExternalID: artifact.ExternalId, + State: m.MapFromArtifactState(artifact.State), + CustomProperties: &customProps, } return modelArtifact, nil diff --git a/internal/testutils/test_container_utils.go b/internal/testutils/test_container_utils.go new file mode 100644 index 00000000..441bfd01 --- /dev/null +++ b/internal/testutils/test_container_utils.go @@ -0,0 +1,106 @@ +package testutils + +import ( + "context" + "fmt" + "os" + "testing" + + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/testcontainers/testcontainers-go" + "github.com/testcontainers/testcontainers-go/wait" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +const ( + useProvider = testcontainers.ProviderDefault // or explicit to testcontainers.ProviderPodman if needed + mlmdImage = "gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0" + sqliteFile = "metadata.sqlite.db" + testConfigFolder = "test/config/ml-metadata" +) + +func clearMetadataSqliteDB(wd string) error { + if err := os.Remove(fmt.Sprintf("%s/%s", wd, sqliteFile)); err != nil { + return fmt.Errorf("expected to clear sqlite file but didn't find: %v", err) + } + return nil +} + +// SetupMLMDTestContainer creates a MLMD gRPC test container +// Returns +// - gRPC client connection to the test container +// - ml-metadata client used to double check the database +// - teardown function +func SetupMLMDTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { + ctx := context.Background() + wd, err := os.Getwd() + if err != nil { + t.Errorf("error getting working directory: %v", err) + } + wd = fmt.Sprintf("%s/../../%s", wd, testConfigFolder) + t.Logf("using working directory: %s", wd) + + req := testcontainers.ContainerRequest{ + Image: mlmdImage, + ExposedPorts: []string{"8080/tcp"}, + Env: map[string]string{ + "METADATA_STORE_SERVER_CONFIG_FILE": "/tmp/shared/conn_config.pb", + }, + Mounts: testcontainers.ContainerMounts{ + testcontainers.ContainerMount{ + Source: testcontainers.GenericBindMountSource{ + HostPath: wd, + }, + Target: "/tmp/shared", + }, + }, + WaitingFor: wait.ForLog("Server listening on"), + } + + mlmdgrpc, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ + ProviderType: useProvider, + ContainerRequest: req, + Started: true, + }) + if err != nil { + t.Errorf("error setting up mlmd grpc container: %v", err) + } + + mappedHost, err := mlmdgrpc.Host(ctx) + if err != nil { + t.Error(err) + } + mappedPort, err := mlmdgrpc.MappedPort(ctx, "8080") + if err != nil { + t.Error(err) + } + mlmdAddr := fmt.Sprintf("%s:%s", mappedHost, mappedPort.Port()) + t.Log("MLMD test container setup at: ", mlmdAddr) + + // setup grpc connection + conn, err := grpc.DialContext( + context.Background(), + mlmdAddr, + grpc.WithReturnConnectionError(), + grpc.WithBlock(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + t.Errorf("error dialing connection to mlmd server %s: %v", mlmdAddr, err) + } + + mlmdClient := proto.NewMetadataStoreServiceClient(conn) + + return conn, mlmdClient, func(t *testing.T) { + if err := conn.Close(); err != nil { + t.Error(err) + } + if err := mlmdgrpc.Terminate(ctx); err != nil { + t.Error(err) + } + if err := clearMetadataSqliteDB(wd); err != nil { + t.Error(err) + } + } +} diff --git a/test/bdd/mr_service_features_test.go b/test/bdd/mr_service_features_test.go index 5def7f11..0860bea2 100644 --- a/test/bdd/mr_service_features_test.go +++ b/test/bdd/mr_service_features_test.go @@ -5,7 +5,6 @@ import ( "fmt" "log" "os" - "strconv" "testing" "github.com/cucumber/godog" @@ -80,38 +79,19 @@ func iStoreARegisteredModelWithNameAndAChildModelVersionWithNameAndAChildArtifac if err != nil { return err } - registeredModelId, err := idToInt64(*registeredModel.Id) - if err != nil { - return err - } var modelVersion *openapi.ModelVersion - if modelVersion, err = service.UpsertModelVersion(&openapi.ModelVersion{Name: &modelVersionName}, (*core.BaseResourceId)(registeredModelId)); err != nil { - return err - } - modelVersionId, err := idToInt64(*modelVersion.Id) - if err != nil { + if modelVersion, err = service.UpsertModelVersion(&openapi.ModelVersion{Name: &modelVersionName}, registeredModel.Id); err != nil { return err } - if _, err = service.UpsertModelArtifact(&openapi.ModelArtifact{Uri: &artifactURI}, (*core.BaseResourceId)(modelVersionId)); err != nil { + if _, err = service.UpsertModelArtifact(&openapi.ModelArtifact{Uri: &artifactURI}, modelVersion.Id); err != nil { return err } return nil } -func idToInt64(idString string) (*int64, error) { - idInt, err := strconv.Atoi(idString) - if err != nil { - return nil, err - } - - idInt64 := int64(idInt) - - return &idInt64, nil -} - func thereShouldBeAMlmdContextOfTypeNamed(ctx context.Context, arg1, arg2 string) error { conn := ctx.Value(connCtxKey{}).(*grpc.ClientConn) client := proto.NewMetadataStoreServiceClient(conn) @@ -183,7 +163,7 @@ func InitializeScenario(ctx *godog.ScenarioContext) { return ctx, err } wd := ctx.Value(wdCtxKey{}).(string) - clearMetadataSqliteDB(wd) + _ = clearMetadataSqliteDB(wd) return ctx, nil }) } From 2561513a178d95d1108d2f53c764eafa67a514dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 16:43:32 +0000 Subject: [PATCH 087/254] Bump github.com/docker/docker (#111) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index cd0f5557..3bf034c9 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cucumber/godog v0.13.0 github.com/docker/distribution v2.8.2+incompatible // indirect - github.com/docker/docker v24.0.6+incompatible // indirect + github.com/docker/docker v24.0.7+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect diff --git a/go.sum b/go.sum index 8ae685a1..095297ac 100644 --- a/go.sum +++ b/go.sum @@ -92,8 +92,8 @@ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+ github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.6+incompatible h1:hceabKCtUgDqPu+qm0NgsaXf28Ljf4/pWFL7xjWWDgE= -github.com/docker/docker v24.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= +github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= From 1d29332dd813262f56199d9ac7e905947c5b2ae6 Mon Sep 17 00:00:00 2001 From: Isabella Basso Date: Mon, 30 Oct 2023 14:56:47 -0300 Subject: [PATCH 088/254] workflows: fix branch restriction on pull requests (#112) As we actually want to run those workflows for any branches, we should either specify "**" to include names with slashes (/) or simply omit the restriction. Signed-off-by: Isabella Basso do Amaral --- .github/workflows/build-image-pr.yml | 4 +--- .github/workflows/build.yml | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index 7032c826..aea18ba1 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -2,8 +2,6 @@ name: Test container image build on: pull_request_target: - branches: - - '*' paths-ignore: - 'LICENSE*' - '**.gitignore' @@ -33,4 +31,4 @@ jobs: shell: bash env: VERSION: ${{ steps.tags.outputs.tag }} - run: ./scripts/build_deploy.sh \ No newline at end of file + run: ./scripts/build_deploy.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5039e223..5dc2d7ab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,8 +5,6 @@ on: branches: - 'main' pull_request: - branches: - - '*' paths-ignore: - 'LICENSE*' - 'DOCKERFILE*' From 9fc3c30b0de7de7f253b12c848b30ba55ec9dccd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 08:50:41 +0000 Subject: [PATCH 089/254] Bump github.com/google/uuid from 1.3.1 to 1.4.0 (#114) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 3bf034c9..85f6d464 100644 --- a/go.mod +++ b/go.mod @@ -59,7 +59,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/uuid v1.3.1 + github.com/google/uuid v1.4.0 github.com/gorilla/websocket v1.5.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect diff --git a/go.sum b/go.sum index 095297ac..8041b648 100644 --- a/go.sum +++ b/go.sum @@ -183,8 +183,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= +github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= From 2fe3c9d55c81ef85786d20c1277533c4ea28120c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 08:51:47 +0000 Subject: [PATCH 090/254] Bump gorm.io/driver/sqlite from 1.5.3 to 1.5.4 (#115) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 85f6d464..9b2a9421 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 - gorm.io/driver/sqlite v1.5.3 + gorm.io/driver/sqlite v1.5.4 gorm.io/gorm v1.25.5 ) diff --git a/go.sum b/go.sum index 8041b648..02dcdc09 100644 --- a/go.sum +++ b/go.sum @@ -687,8 +687,8 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/sqlite v1.5.3 h1:7/0dUgX28KAcopdfbRWWl68Rflh6osa4rDh+m51KL2g= -gorm.io/driver/sqlite v1.5.3/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= +gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0= +gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= From fe5a522aec336180f6450d0463428f297814fa81 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 08:52:54 +0000 Subject: [PATCH 091/254] Bump github.com/99designs/gqlgen from 0.17.36 to 0.17.40 (#116) --- go.mod | 3 ++- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 9b2a9421..41571ce2 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/opendatahub-io/model-registry go 1.19 require ( - github.com/99designs/gqlgen v0.17.36 + github.com/99designs/gqlgen v0.17.40 github.com/go-chi/chi/v5 v5.0.10 github.com/golang/glog v1.1.2 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 @@ -35,6 +35,7 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sosodev/duration v1.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect diff --git a/go.sum b/go.sum index 02dcdc09..edcccf9c 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/99designs/gqlgen v0.17.36 h1:u/o/rv2SZ9s5280dyUOOrkpIIkr/7kITMXYD3rkJ9go= -github.com/99designs/gqlgen v0.17.36/go.mod h1:6RdyY8puhCoWAQVr2qzF2OMVfudQzc8ACxzpzluoQm4= +github.com/99designs/gqlgen v0.17.40 h1:/l8JcEVQ93wqIfmH9VS1jsAkwm6eAF1NwQn3N+SDqBY= +github.com/99designs/gqlgen v0.17.40/go.mod h1:b62q1USk82GYIVjC60h02YguAZLqYZtvWml8KkhJps4= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= @@ -295,6 +295,8 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0 github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sosodev/duration v1.1.0 h1:kQcaiGbJaIsRqgQy7VGlZrVw1giWO+lDoX3MCPnpVO4= +github.com/sosodev/duration v1.1.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= From 7f452cf9d44dd546a8c66c624ece4dcfd20d5700 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 08:54:30 +0000 Subject: [PATCH 092/254] Bump github.com/testcontainers/testcontainers-go from 0.25.0 to 0.26.0 (#117) --- go.mod | 15 ++++++++------- go.sum | 31 +++++++++++++++++-------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/go.mod b/go.mod index 41571ce2..b858c11a 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.17.0 github.com/stretchr/testify v1.8.4 - github.com/testcontainers/testcontainers-go v0.25.0 + github.com/testcontainers/testcontainers-go v0.26.0 github.com/vektah/gqlparser/v2 v2.5.10 golang.org/x/sync v0.4.0 google.golang.org/grpc v1.59.0 @@ -25,6 +25,7 @@ require ( ) require ( + github.com/containerd/log v0.1.0 // indirect github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect github.com/cucumber/messages/go/v21 v21.0.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -45,10 +46,10 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.0 // indirect + github.com/Microsoft/hcsshim v0.11.1 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/containerd/containerd v1.7.6 // indirect + github.com/containerd/containerd v1.7.7 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/cucumber/godog v0.13.0 @@ -72,12 +73,12 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/patternmatcher v0.5.0 // indirect + github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/image-spec v1.1.0-rc5 // indirect github.com/opencontainers/runc v1.1.5 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect @@ -85,9 +86,9 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/searKing/golang/go v1.2.52 // indirect github.com/searKing/golang/tools v1.2.29 // indirect - github.com/shirou/gopsutil/v3 v3.23.8 // indirect + github.com/shirou/gopsutil/v3 v3.23.9 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/subosito/gotenv v1.6.0 // indirect diff --git a/go.sum b/go.sum index edcccf9c..5fc860ba 100644 --- a/go.sum +++ b/go.sum @@ -47,8 +47,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.0 h1:7EFNIY4igHEXUdj1zXgAyU3fLc7QfOKHbkldRVTBdiM= -github.com/Microsoft/hcsshim v0.11.0/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= +github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= +github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= @@ -67,8 +67,10 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= -github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4= +github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4= +github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= @@ -237,8 +239,8 @@ github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6 github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= -github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= @@ -249,8 +251,8 @@ github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7P github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= -github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= +github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= @@ -283,16 +285,16 @@ github.com/searKing/golang/tools/go-enum v1.2.97 h1:mX396oCnjdGqmMmwffBwpEU3L1X/ github.com/searKing/golang/tools/go-enum v1.2.97/go.mod h1:gWZ/vkIPpA0nCHDMETjzKqsHPDWSPdhZeXPxf/jWyqA= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/shirou/gopsutil/v3 v3.23.8 h1:xnATPiybo6GgdRoC4YoGnxXZFRc3dqQTGi73oLvvBrE= -github.com/shirou/gopsutil/v3 v3.23.8/go.mod h1:7hmCaBn+2ZwaZOr6jmPBZDfawwMGuo1id3C6aM8EDqQ= +github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= +github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= -github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sosodev/duration v1.1.0 h1:kQcaiGbJaIsRqgQy7VGlZrVw1giWO+lDoX3MCPnpVO4= @@ -326,8 +328,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/testcontainers/testcontainers-go v0.25.0 h1:erH6cQjsaJrH+rJDU9qIf89KFdhK0Bft0aEZHlYC3Vs= -github.com/testcontainers/testcontainers-go v0.25.0/go.mod h1:4sC9SiJyzD1XFi59q8umTQYWxnkweEc5OjVtTUlJzqQ= +github.com/testcontainers/testcontainers-go v0.26.0 h1:uqcYdoOHBy1ca7gKODfBd9uTHVK3a7UL848z09MVZ0c= +github.com/testcontainers/testcontainers-go v0.26.0/go.mod h1:ICriE9bLX5CLxL9OFQ2N+2N+f+803LNJ1utJb1+Inx0= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= @@ -506,6 +508,7 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From 888c3cd0dcd9324ae552da158157473b4e47abe3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 09:00:42 +0000 Subject: [PATCH 093/254] Bump github.com/grpc-ecosystem/go-grpc-middleware/v2 from 2.0.0 to 2.0.1 (#118) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b858c11a..6b3fce08 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/99designs/gqlgen v0.17.40 github.com/go-chi/chi/v5 v5.0.10 github.com/golang/glog v1.1.2 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 github.com/searKing/golang/tools/go-enum v1.2.97 github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.7.0 diff --git a/go.sum b/go.sum index 5fc860ba..bd5c215b 100644 --- a/go.sum +++ b/go.sum @@ -192,8 +192,8 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0 h1:2cz5kSrxzMYHiWOBbKj8itQm+nRykkB8aMv4ThcHYHA= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 h1:HcUWd006luQPljE73d5sk+/VgYPGUReEVz2y1/qylwY= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= From fe762a1d7b82a7195b4c1db52958fcb44d60ad7f Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Tue, 31 Oct 2023 10:33:43 +0100 Subject: [PATCH 094/254] Improve core layer optional params management (#113) * Improve core layer optional params management * Use glog in core layer * Apply suggestions from code review Co-authored-by: Matteo Mortari --------- Co-authored-by: Matteo Mortari --- internal/core/core.go | 201 +++++++++++++--- internal/core/core_test.go | 347 +++++++++++++++++++++++----- internal/core/mapper/mlmd_mapper.go | 5 +- 3 files changed, 463 insertions(+), 90 deletions(-) diff --git a/internal/core/core.go b/internal/core/core.go index 386c9e94..29fce80b 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -5,6 +5,7 @@ import ( "fmt" "log" + "github.com/golang/glog" "github.com/opendatahub-io/model-registry/internal/core/mapper" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" @@ -79,10 +80,24 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err // REGISTERED MODELS func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) { + var err error + var existing *openapi.RegisteredModel + if registeredModel.Id == nil { - log.Printf("Creating registered model for %s", *registeredModel.Name) + glog.Info("Creating new registered model") } else { - log.Printf("Updating registered model %s for %s", *registeredModel.Id, *registeredModel.Name) + glog.Info("Updating registered model %s", *registeredModel.Id) + existing, err = serv.GetRegisteredModelById(*registeredModel.Id) + if err != nil { + return nil, err + } + } + + // if already existing assure the name is the same + if existing != nil && registeredModel.Name == nil { + // user did not provide it + // need to set it to avoid mlmd error "context name should not be empty" + registeredModel.Name = existing.Name } modelCtx, err := serv.mapper.MapFromRegisteredModel(registeredModel) @@ -109,7 +124,7 @@ func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi } func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) { - log.Printf("Getting registered model %s", id) + glog.Info("Getting registered model %s", id) idAsInt, err := mapper.IdToInt64(id) if err != nil { @@ -123,10 +138,14 @@ func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.Re return nil, err } - if len(getByIdResp.Contexts) != 1 { + if len(getByIdResp.Contexts) > 1 { return nil, fmt.Errorf("multiple registered models found for id %s", id) } + if len(getByIdResp.Contexts) == 0 { + return nil, fmt.Errorf("no registered model found for id %s", id) + } + regModel, err := serv.mapper.MapToRegisteredModel(getByIdResp.Contexts[0]) if err != nil { return nil, err @@ -135,14 +154,47 @@ func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.Re return regModel, nil } +func (serv *modelRegistryService) getRegisteredModelByVersionId(id string) (*openapi.RegisteredModel, error) { + glog.Info("Getting registered model for model version %s", id) + + idAsInt, err := mapper.IdToInt64(id) + if err != nil { + return nil, err + } + + getParentResp, err := serv.mlmdClient.GetParentContextsByContext(context.Background(), &proto.GetParentContextsByContextRequest{ + ContextId: idAsInt, + }) + if err != nil { + return nil, err + } + + if len(getParentResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple registered models found for model version %s", id) + } + + if len(getParentResp.Contexts) == 0 { + return nil, fmt.Errorf("no registered model found for model version %s", id) + } + + regModel, err := serv.mapper.MapToRegisteredModel(getParentResp.Contexts[0]) + if err != nil { + return nil, err + } + + return regModel, nil +} + func (serv *modelRegistryService) GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) { - log.Printf("Getting registered model by params name=%v, externalId=%v", name, externalId) + glog.Info("Getting registered model by params name=%v, externalId=%v", name, externalId) filterQuery := "" if name != nil { filterQuery = fmt.Sprintf("name = \"%s\"", *name) } else if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) + } else { + return nil, fmt.Errorf("invalid parameters call, supply either name or externalId") } getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ @@ -200,26 +252,46 @@ func (serv *modelRegistryService) GetRegisteredModels(listOptions ListOptions) ( // MODEL VERSIONS func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *string) (*openapi.ModelVersion, error) { + var err error + var existing *openapi.ModelVersion + var registeredModel *openapi.RegisteredModel + if modelVersion.Id == nil { - log.Printf("Creating model version") + // create + glog.Info("Creating new model version") + if parentResourceId == nil { + return nil, fmt.Errorf("missing registered model id, cannot create model version without registered model") + } + registeredModel, err = serv.GetRegisteredModelById(*parentResourceId) + if err != nil { + return nil, err + } } else { - log.Printf("Updating model version %s", *modelVersion.Id) - } - - if parentResourceId == nil { - return nil, fmt.Errorf("missing registered model id, cannot create model version without registered model") + // update + glog.Info("Updating model version %s", *modelVersion.Id) + existing, err = serv.GetModelVersionById(*modelVersion.Id) + if err != nil { + return nil, err + } + registeredModel, err = serv.getRegisteredModelByVersionId(*modelVersion.Id) + if err != nil { + return nil, err + } } - registeredModel, err := serv.GetRegisteredModelById(*parentResourceId) - if err != nil { - return nil, fmt.Errorf("not a valid registered model id: %s", *parentResourceId) - } - registeredModelIdCtxID, err := mapper.IdToInt64(*registeredModel.Id) + registeredModelId, err := mapper.IdToInt64(*registeredModel.Id) if err != nil { return nil, err } - registeredModelName := registeredModel.Name - modelCtx, err := serv.mapper.MapFromModelVersion(modelVersion, *registeredModelIdCtxID, registeredModelName) + + // if already existing assure the name is the same + if existing != nil && modelVersion.Name == nil { + // user did not provide it + // need to set it to avoid mlmd error "context name should not be empty" + modelVersion.Name = existing.Name + } + + modelCtx, err := serv.mapper.MapFromModelVersion(modelVersion, *registeredModelId, registeredModel.Name) if err != nil { return nil, err } @@ -238,7 +310,7 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ ParentContexts: []*proto.ParentContext{{ ChildId: modelId, - ParentId: registeredModelIdCtxID}}, + ParentId: registeredModelId}}, TransactionOptions: &proto.TransactionOptions{}, }) if err != nil { @@ -268,10 +340,14 @@ func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.Model return nil, err } - if len(getByIdResp.Contexts) != 1 { + if len(getByIdResp.Contexts) > 1 { return nil, fmt.Errorf("multiple model versions found for id %s", id) } + if len(getByIdResp.Contexts) == 0 { + return nil, fmt.Errorf("no model version found for id %s", id) + } + modelVer, err := serv.mapper.MapToModelVersion(getByIdResp.Contexts[0]) if err != nil { return nil, err @@ -280,6 +356,37 @@ func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.Model return modelVer, nil } +func (serv *modelRegistryService) getModelVersionByArtifactId(id string) (*openapi.ModelVersion, error) { + glog.Info("Getting model version for model artifact %s", id) + + idAsInt, err := mapper.IdToInt64(id) + if err != nil { + return nil, err + } + + getParentResp, err := serv.mlmdClient.GetContextsByArtifact(context.Background(), &proto.GetContextsByArtifactRequest{ + ArtifactId: idAsInt, + }) + if err != nil { + return nil, err + } + + if len(getParentResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple model versions found for model artifact %s", id) + } + + if len(getParentResp.Contexts) == 0 { + return nil, fmt.Errorf("no model version found for model artifact %s", id) + } + + modelVersion, err := serv.mapper.MapToModelVersion(getParentResp.Contexts[0]) + if err != nil { + return nil, err + } + + return modelVersion, nil +} + func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) { filterQuery := "" if versionName != nil && parentResourceId != nil { @@ -290,6 +397,8 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned(idAsInt, *versionName)) } else if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) + } else { + return nil, fmt.Errorf("invalid parameters call, supply either (versionName and parentResourceId), or externalId") } getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ @@ -353,17 +462,47 @@ func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, pare // MODEL ARTIFACTS func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *string) (*openapi.ModelArtifact, error) { + var err error + var existing *openapi.ModelArtifact + if modelArtifact.Id == nil { - log.Printf("Creating model artifact") + // create + glog.Info("Creating new model artifact") + if parentResourceId == nil { + return nil, fmt.Errorf("missing model version id, cannot create model artifact without model version") + } + _, err = serv.GetModelVersionById(*parentResourceId) + if err != nil { + return nil, err + } } else { - log.Printf("Updating model artifact %s", *modelArtifact.Id) + // update + glog.Info("Updating model artifact %s", *modelArtifact.Id) + existing, err = serv.GetModelArtifactById(*modelArtifact.Id) + if err != nil { + return nil, err + } + _, err = serv.getModelVersionByArtifactId(*modelArtifact.Id) + if err != nil { + return nil, err + } } - idAsInt, err := mapper.IdToInt64(*parentResourceId) + modelVersionId, err := mapper.IdToInt64(*parentResourceId) if err != nil { return nil, err } - artifact := serv.mapper.MapFromModelArtifact(*modelArtifact, idAsInt) + + // if already existing assure the name is the same + if existing != nil { + if modelArtifact.Name == nil { + // user did not provide it + // need to set it to avoid mlmd error "artifact name should not be empty" + modelArtifact.Name = existing.Name + } + } + + artifact := serv.mapper.MapFromModelArtifact(*modelArtifact, modelVersionId) artifactsResp, err := serv.mlmdClient.PutArtifacts(context.Background(), &proto.PutArtifactsRequest{ Artifacts: []*proto.Artifact{artifact}, @@ -374,14 +513,10 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod // add explicit association between artifacts and model version if parentResourceId != nil && modelArtifact.Id == nil { - modelVersionIdCtx, err := mapper.IdToInt64(*parentResourceId) - if err != nil { - return nil, err - } attributions := []*proto.Attribution{} for _, a := range artifactsResp.ArtifactIds { attributions = append(attributions, &proto.Attribution{ - ContextId: modelVersionIdCtx, + ContextId: modelVersionId, ArtifactId: &a, }) } @@ -415,6 +550,14 @@ func (serv *modelRegistryService) GetModelArtifactById(id string) (*openapi.Mode return nil, err } + if len(artifactsResp.Artifacts) > 1 { + return nil, fmt.Errorf("multiple model artifacts found for id %s", id) + } + + if len(artifactsResp.Artifacts) == 0 { + return nil, fmt.Errorf("no model artifact found for id %s", id) + } + result, err := serv.mapper.MapToModelArtifact(artifactsResp.Artifacts[0]) if err != nil { return nil, err diff --git a/internal/core/core_test.go b/internal/core/core_test.go index c912d9d1..29e45821 100644 --- a/internal/core/core_test.go +++ b/internal/core/core_test.go @@ -183,17 +183,18 @@ func TestCreateRegisteredModel(t *testing.T) { assertion.Nilf(err, "error creating registered model: %v", err) assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") - byTypeAndNameResp, err := client.GetContextByTypeAndName(context.Background(), &proto.GetContextByTypeAndNameRequest{ - TypeName: &core.RegisteredModelTypeName, - ContextName: &modelName, + createdModelId, _ := mapper.IdToInt64(*createdModel.Id) + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*createdModelId}, }) assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - ctxId := mapper.IdToString(*byTypeAndNameResp.Context.Id) + ctx := ctxById.Contexts[0] + ctxId := mapper.IdToString(*ctx.Id) assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") - assertion.Equal(modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") - assertion.Equal(modelExternalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") - assertion.Equal(owner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") + assertion.Equal(modelExternalId, *ctx.ExternalId, "saved external id should match the provided one") + assertion.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) @@ -226,28 +227,13 @@ func TestUpdateRegisteredModel(t *testing.T) { // checks assertion.Nilf(err, "error creating registered model: %v", err) assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") + createdModelId, _ := mapper.IdToInt64(*createdModel.Id) // checks created model matches original one except for Id assertion.Equal(*registeredModel.Name, *createdModel.Name, "returned model name should match the original one") assertion.Equal(*registeredModel.ExternalID, *createdModel.ExternalID, "returned model external id should match the original one") assertion.Equal(*registeredModel.CustomProperties, *createdModel.CustomProperties, "returned model custom props should match the original one") - byTypeAndNameResp, err := client.GetContextByTypeAndName(context.Background(), &proto.GetContextByTypeAndNameRequest{ - TypeName: &core.RegisteredModelTypeName, - ContextName: &modelName, - }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - - ctxId := mapper.IdToString(*byTypeAndNameResp.Context.Id) - assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") - assertion.Equal(modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") - assertion.Equal(modelExternalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") - assertion.Equal(owner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") - - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") - // update existing model newModelExternalId := "newExternalId" newOwner := "newOwner" @@ -263,22 +249,46 @@ func TestUpdateRegisteredModel(t *testing.T) { createdModel, err = service.UpsertRegisteredModel(createdModel) assertion.Nilf(err, "error creating registered model: %v", err) + // still one registered model + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*createdModelId}, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + ctxId := mapper.IdToString(*ctx.Id) + assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") + assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") + assertion.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") + assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + + // update the model keeping nil name + newModelExternalId = "newNewExternalId" + createdModel.ExternalID = &newModelExternalId + createdModel.Name = nil + createdModel, err = service.UpsertRegisteredModel(createdModel) + assertion.Nilf(err, "error creating registered model: %v", err) + // still one registered model getAllResp, err = client.GetContexts(context.Background(), &proto.GetContextsRequest{}) assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") - byTypeAndNameResp, err = client.GetContextByTypeAndName(context.Background(), &proto.GetContextByTypeAndNameRequest{ - TypeName: &core.RegisteredModelTypeName, - ContextName: &modelName, + ctxById, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*createdModelId}, }) assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - ctxId = mapper.IdToString(*byTypeAndNameResp.Context.Id) + ctx = ctxById.Contexts[0] + ctxId = mapper.IdToString(*ctx.Id) assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") - assertion.Equal(modelName, *byTypeAndNameResp.Context.Name, "saved model name should match the provided one") - assertion.Equal(newModelExternalId, *byTypeAndNameResp.Context.ExternalId, "saved external id should match the provided one") - assertion.Equal(newOwner, byTypeAndNameResp.Context.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") + assertion.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") + assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") } func TestGetRegisteredModelById(t *testing.T) { @@ -360,6 +370,27 @@ func TestGetRegisteredModelByParamsExternalId(t *testing.T) { assertion.Equalf(*createdModel.Id, *byName.Id, "the returned model id should match the retrieved by name") } +func TestGetRegisteredModelByEmptyParams(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new model + registeredModel := &openapi.RegisteredModel{ + Name: &modelName, + ExternalID: &modelExternalId, + } + + _, err := service.UpsertRegisteredModel(registeredModel) + assertion.Nilf(err, "error creating registered model: %v", err) + + _, err = service.GetRegisteredModelByParams(nil, nil) + assertion.NotNil(err) + assertion.Equal("invalid parameters call, supply either name or externalId", err.Error()) +} + func TestGetRegisteredModelsOrderedById(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) @@ -533,33 +564,6 @@ func TestGetRegisteredModelsWithPageSize(t *testing.T) { // MODEL VERSIONS -func TestCreateModelVersionWithInvalidRegisteredModelId(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - - // create mode registry service - service := initModelRegistryService(assertion, conn) - - notExistingRegisteredModelId := "9999" - - modelVersion := &openapi.ModelVersion{ - Name: &modelVersionName, - ExternalID: &versionExternalId, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, - } - - createdVersion, err := service.UpsertModelVersion(modelVersion, ¬ExistingRegisteredModelId) - assertion.NotNil(err, "model version should fail because registered model id does not exist") - assertion.Equal(fmt.Sprintf("not a valid registered model id: %s", notExistingRegisteredModelId), err.Error()) - assertion.Nil(createdVersion) -} - func TestCreateModelVersion(t *testing.T) { assertion, conn, client, teardown := setup(t) defer teardown(t) @@ -607,6 +611,36 @@ func TestCreateModelVersion(t *testing.T) { assertion.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") } +func TestCreateModelVersionFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := "9999" + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + _, err := service.UpsertModelVersion(modelVersion, nil) + assertion.NotNil(err) + assertion.Equal("missing registered model id, cannot create model version without registered model", err.Error()) + + _, err = service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.NotNil(err) + assertion.Equal("no registered model found for id 9999", err.Error()) +} + func TestUpdateModelVersion(t *testing.T) { assertion, conn, client, teardown := setup(t) defer teardown(t) @@ -645,7 +679,7 @@ func TestUpdateModelVersion(t *testing.T) { } updatedVersion, err := service.UpsertModelVersion(createdVersion, ®isteredModelId) - assertion.Nilf(err, "error updating new model version for %d: %v", registeredModelId, err) + assertion.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) updateVersionId, _ := mapper.IdToInt64(*updatedVersion.Id) assertion.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") @@ -669,6 +703,73 @@ func TestUpdateModelVersion(t *testing.T) { assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) fmt.Printf("%+v", getAllResp.Contexts) assertion.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") + + // update with nil name + newExternalId = "org.my_awesome_model_@v1" + updatedVersion.ExternalID = &newExternalId + updatedVersion.Name = nil + updatedVersion, err = service.UpsertModelVersion(updatedVersion, ®isteredModelId) + assertion.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) + + updateVersionId, _ = mapper.IdToInt64(*updatedVersion.Id) + assertion.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") + + byId, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *updateVersionId, + }, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + + assertion.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") + assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") + assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + assertion.Equalf(core.ModelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", core.ModelVersionTypeName) +} + +func TestUpdateModelVersionFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %s", registeredModelId) + assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + + newExternalId := "org.my_awesome_model@v1" + newScore := 0.95 + + createdVersion.ExternalID = &newExternalId + (*createdVersion.CustomProperties)["score"] = openapi.MetadataValue{ + MetadataDoubleValue: &openapi.MetadataDoubleValue{ + DoubleValue: &newScore, + }, + } + + wrongId := "9999" + createdVersion.Id = &wrongId + _, err = service.UpsertModelVersion(createdVersion, ®isteredModelId) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("no model version found for id %s", wrongId), err.Error()) } func TestGetModelVersionById(t *testing.T) { @@ -803,6 +904,36 @@ func TestGetModelVersionByParamsExternalId(t *testing.T) { assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByExternalId.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") } +func TestGetModelVersionByEmptyParams(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + + _, err = service.GetModelVersionByParams(nil, nil, nil) + assertion.NotNil(err) + assertion.Equal("invalid parameters call, supply either (versionName and parentResourceId), or externalId", err.Error()) +} + func TestGetModelVersions(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) @@ -957,6 +1088,37 @@ func TestCreateModelArtifact(t *testing.T) { assertion.Equal(*createdArtifactId, *byCtx.Artifacts[0].Id) } +func TestCreateModelArtifactFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := "9998" + + modelArtifact := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + _, err := service.UpsertModelArtifact(modelArtifact, nil) + assertion.NotNil(err) + assertion.Equal("missing model version id, cannot create model artifact without model version", err.Error()) + + _, err = service.UpsertModelArtifact(modelArtifact, &modelVersionId) + assertion.NotNil(err) + assertion.Equal("no model version found for id 9998", err.Error()) +} + func TestUpdateModelArtifact(t *testing.T) { assertion, conn, client, teardown := setup(t) defer teardown(t) @@ -1003,6 +1165,44 @@ func TestUpdateModelArtifact(t *testing.T) { assertion.Equal(*(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["author"].GetStringValue()) } +func TestUpdateModelArtifactFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + modelArtifact := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for model version %s", modelVersionId) + assertion.NotNilf(createdArtifact.Id, "created model artifact should not have nil Id") + + newState := "MARKED_FOR_DELETION" + createdArtifact.State = (*openapi.ArtifactState)(&newState) + updatedArtifact, err := service.UpsertModelArtifact(createdArtifact, &modelVersionId) + assertion.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) + + wrongId := "9998" + updatedArtifact.Id = &wrongId + _, err = service.UpsertModelArtifact(updatedArtifact, &modelVersionId) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("no model artifact found for id %s", wrongId), err.Error()) +} + func TestGetModelArtifactById(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) @@ -1098,6 +1298,37 @@ func TestGetModelArtifactByParams(t *testing.T) { assertion.Equal(*createdArtifact, *getByExtId, "artifacts returned during creation and on get by ext id should be equal") } +func TestGetModelArtifactByEmptyParams(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + modelArtifact := &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + ExternalID: &artifactExtId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + _, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) + assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + + _, err = service.GetModelArtifactByParams(nil, nil, nil) + assertion.NotNil(err) + assertion.Equal("invalid parameters call, supply either (artifactName and parentResourceId), or externalId", err.Error()) +} + func TestGetModelArtifacts(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) diff --git a/internal/core/mapper/mlmd_mapper.go b/internal/core/mapper/mlmd_mapper.go index 1d4adbae..dc45f7b1 100644 --- a/internal/core/mapper/mlmd_mapper.go +++ b/internal/core/mapper/mlmd_mapper.go @@ -108,7 +108,6 @@ func (m *Mapper) MapToArtifactState(oapiState *openapi.ArtifactState) *proto.Art } func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel) (*proto.Context, error) { - var idInt *int64 if registeredModel.Id != nil { var err error @@ -124,10 +123,10 @@ func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel } return &proto.Context{ - Name: registeredModel.Name, + Id: idInt, TypeId: &m.RegisteredModelTypeId, + Name: registeredModel.Name, ExternalId: registeredModel.ExternalID, - Id: idInt, CustomProperties: customProps, }, nil } From e2c190ad010ae0cba3575194d2a5189d577cc2ad Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Tue, 31 Oct 2023 10:41:02 -0700 Subject: [PATCH 095/254] Add property description to BaseResourceUpdate (#119) --- api/openapi/model-registry.yaml | 4 ++ internal/model/openapi/model_base_artifact.go | 37 +++++++++++++++++++ .../openapi/model_base_artifact_create.go | 37 +++++++++++++++++++ .../openapi/model_base_artifact_update.go | 37 +++++++++++++++++++ .../model/openapi/model_base_execution.go | 37 +++++++++++++++++++ .../openapi/model_base_execution_create.go | 37 +++++++++++++++++++ .../openapi/model_base_execution_update.go | 37 +++++++++++++++++++ internal/model/openapi/model_base_resource.go | 37 +++++++++++++++++++ .../openapi/model_base_resource_create.go | 37 +++++++++++++++++++ .../openapi/model_base_resource_update.go | 37 +++++++++++++++++++ .../model/openapi/model_inference_service.go | 37 +++++++++++++++++++ .../openapi/model_inference_service_create.go | 37 +++++++++++++++++++ .../openapi/model_inference_service_update.go | 37 +++++++++++++++++++ .../model/openapi/model_model_artifact.go | 37 +++++++++++++++++++ .../openapi/model_model_artifact_create.go | 37 +++++++++++++++++++ .../openapi/model_model_artifact_update.go | 37 +++++++++++++++++++ internal/model/openapi/model_model_version.go | 37 +++++++++++++++++++ .../openapi/model_model_version_create.go | 37 +++++++++++++++++++ .../openapi/model_model_version_update.go | 37 +++++++++++++++++++ .../model/openapi/model_registered_model.go | 37 +++++++++++++++++++ .../openapi/model_registered_model_create.go | 37 +++++++++++++++++++ .../openapi/model_registered_model_update.go | 37 +++++++++++++++++++ internal/model/openapi/model_serve_model.go | 37 +++++++++++++++++++ .../model/openapi/model_serve_model_create.go | 37 +++++++++++++++++++ .../model/openapi/model_serve_model_update.go | 37 +++++++++++++++++++ .../openapi/model_serving_environment.go | 37 +++++++++++++++++++ .../model_serving_environment_create.go | 37 +++++++++++++++++++ .../model_serving_environment_update.go | 37 +++++++++++++++++++ 28 files changed, 1003 insertions(+) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index 44bc985d..b4991d2f 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -1269,6 +1269,10 @@ components: type: object additionalProperties: $ref: '#/components/schemas/MetadataValue' + description: + description: |- + An optional description about the resource. + type: string externalID: description: |- The external id that come from the clients’ system. This field is optional. diff --git a/internal/model/openapi/model_base_artifact.go b/internal/model/openapi/model_base_artifact.go index 3908cc5f..5e0fb9a1 100644 --- a/internal/model/openapi/model_base_artifact.go +++ b/internal/model/openapi/model_base_artifact.go @@ -21,6 +21,8 @@ var _ MappedNullable = &BaseArtifact{} type BaseArtifact struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. @@ -91,6 +93,38 @@ func (o *BaseArtifact) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseArtifact) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifact) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseArtifact) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseArtifact) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseArtifact) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -352,6 +386,9 @@ func (o BaseArtifact) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_artifact_create.go b/internal/model/openapi/model_base_artifact_create.go index aa17d8ea..2f5f50da 100644 --- a/internal/model/openapi/model_base_artifact_create.go +++ b/internal/model/openapi/model_base_artifact_create.go @@ -21,6 +21,8 @@ var _ MappedNullable = &BaseArtifactCreate{} type BaseArtifactCreate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. @@ -83,6 +85,38 @@ func (o *BaseArtifactCreate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseArtifactCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseArtifactCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseArtifactCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseArtifactCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -224,6 +258,9 @@ func (o BaseArtifactCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_artifact_update.go b/internal/model/openapi/model_base_artifact_update.go index dbea5828..e24b2faf 100644 --- a/internal/model/openapi/model_base_artifact_update.go +++ b/internal/model/openapi/model_base_artifact_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &BaseArtifactUpdate{} type BaseArtifactUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. @@ -81,6 +83,38 @@ func (o *BaseArtifactUpdate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseArtifactUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseArtifactUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseArtifactUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseArtifactUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseArtifactUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -190,6 +224,9 @@ func (o BaseArtifactUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_execution.go b/internal/model/openapi/model_base_execution.go index 24a92fed..45216b32 100644 --- a/internal/model/openapi/model_base_execution.go +++ b/internal/model/openapi/model_base_execution.go @@ -22,6 +22,8 @@ type BaseExecution struct { LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -119,6 +121,38 @@ func (o *BaseExecution) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseExecution) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecution) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseExecution) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseExecution) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseExecution) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -295,6 +329,9 @@ func (o BaseExecution) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_execution_create.go b/internal/model/openapi/model_base_execution_create.go index 51945d99..91908887 100644 --- a/internal/model/openapi/model_base_execution_create.go +++ b/internal/model/openapi/model_base_execution_create.go @@ -22,6 +22,8 @@ type BaseExecutionCreate struct { LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -113,6 +115,38 @@ func (o *BaseExecutionCreate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseExecutionCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseExecutionCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseExecutionCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseExecutionCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -193,6 +227,9 @@ func (o BaseExecutionCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_execution_update.go b/internal/model/openapi/model_base_execution_update.go index 0375043e..44023c28 100644 --- a/internal/model/openapi/model_base_execution_update.go +++ b/internal/model/openapi/model_base_execution_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &BaseExecutionUpdate{} type BaseExecutionUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` @@ -79,6 +81,38 @@ func (o *BaseExecutionUpdate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseExecutionUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseExecutionUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseExecutionUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseExecutionUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseExecutionUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -156,6 +190,9 @@ func (o BaseExecutionUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_resource.go b/internal/model/openapi/model_base_resource.go index aa01540a..544d70fd 100644 --- a/internal/model/openapi/model_base_resource.go +++ b/internal/model/openapi/model_base_resource.go @@ -21,6 +21,8 @@ var _ MappedNullable = &BaseResource{} type BaseResource struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -82,6 +84,38 @@ func (o *BaseResource) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseResource) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResource) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseResource) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseResource) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseResource) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -255,6 +289,9 @@ func (o BaseResource) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_resource_create.go b/internal/model/openapi/model_base_resource_create.go index 493ccd22..13e4e6d3 100644 --- a/internal/model/openapi/model_base_resource_create.go +++ b/internal/model/openapi/model_base_resource_create.go @@ -21,6 +21,8 @@ var _ MappedNullable = &BaseResourceCreate{} type BaseResourceCreate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -76,6 +78,38 @@ func (o *BaseResourceCreate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseResourceCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResourceCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseResourceCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseResourceCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseResourceCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -153,6 +187,9 @@ func (o BaseResourceCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_base_resource_update.go b/internal/model/openapi/model_base_resource_update.go index 1814f4bb..dbf124c8 100644 --- a/internal/model/openapi/model_base_resource_update.go +++ b/internal/model/openapi/model_base_resource_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &BaseResourceUpdate{} type BaseResourceUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` } @@ -74,6 +76,38 @@ func (o *BaseResourceUpdate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *BaseResourceUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *BaseResourceUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *BaseResourceUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *BaseResourceUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *BaseResourceUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -119,6 +153,9 @@ func (o BaseResourceUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_inference_service.go b/internal/model/openapi/model_inference_service.go index 1204f8d3..555197b2 100644 --- a/internal/model/openapi/model_inference_service.go +++ b/internal/model/openapi/model_inference_service.go @@ -21,6 +21,8 @@ var _ MappedNullable = &InferenceService{} type InferenceService struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -90,6 +92,38 @@ func (o *InferenceService) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *InferenceService) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *InferenceService) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *InferenceService) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *InferenceService) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -343,6 +377,9 @@ func (o InferenceService) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_inference_service_create.go b/internal/model/openapi/model_inference_service_create.go index fd25b697..b930ca31 100644 --- a/internal/model/openapi/model_inference_service_create.go +++ b/internal/model/openapi/model_inference_service_create.go @@ -21,6 +21,8 @@ var _ MappedNullable = &InferenceServiceCreate{} type InferenceServiceCreate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -84,6 +86,38 @@ func (o *InferenceServiceCreate) SetCustomProperties(v map[string]MetadataValue) o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *InferenceServiceCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *InferenceServiceCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -241,6 +275,9 @@ func (o InferenceServiceCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_inference_service_update.go b/internal/model/openapi/model_inference_service_update.go index 31b1d982..08527178 100644 --- a/internal/model/openapi/model_inference_service_update.go +++ b/internal/model/openapi/model_inference_service_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &InferenceServiceUpdate{} type InferenceServiceUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. @@ -76,6 +78,38 @@ func (o *InferenceServiceUpdate) SetCustomProperties(v map[string]MetadataValue) o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *InferenceServiceUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *InferenceServiceUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *InferenceServiceUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *InferenceServiceUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -153,6 +187,9 @@ func (o InferenceServiceUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_model_artifact.go b/internal/model/openapi/model_model_artifact.go index 3b064d1b..e4ed3650 100644 --- a/internal/model/openapi/model_model_artifact.go +++ b/internal/model/openapi/model_model_artifact.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ModelArtifact{} type ModelArtifact struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. @@ -103,6 +105,38 @@ func (o *ModelArtifact) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ModelArtifact) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifact) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ModelArtifact) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ModelArtifact) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ModelArtifact) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -556,6 +590,9 @@ func (o ModelArtifact) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_model_artifact_create.go b/internal/model/openapi/model_model_artifact_create.go index cfeb5c0f..83af5c8b 100644 --- a/internal/model/openapi/model_model_artifact_create.go +++ b/internal/model/openapi/model_model_artifact_create.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ModelArtifactCreate{} type ModelArtifactCreate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. @@ -95,6 +97,38 @@ func (o *ModelArtifactCreate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ModelArtifactCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ModelArtifactCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ModelArtifactCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ModelArtifactCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -428,6 +462,9 @@ func (o ModelArtifactCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_model_artifact_update.go b/internal/model/openapi/model_model_artifact_update.go index 2cda6724..979285ed 100644 --- a/internal/model/openapi/model_model_artifact_update.go +++ b/internal/model/openapi/model_model_artifact_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ModelArtifactUpdate{} type ModelArtifactUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. @@ -93,6 +95,38 @@ func (o *ModelArtifactUpdate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ModelArtifactUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelArtifactUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ModelArtifactUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ModelArtifactUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ModelArtifactUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -394,6 +428,9 @@ func (o ModelArtifactUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_model_version.go b/internal/model/openapi/model_model_version.go index 87604daf..335bcb16 100644 --- a/internal/model/openapi/model_model_version.go +++ b/internal/model/openapi/model_model_version.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ModelVersion{} type ModelVersion struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -82,6 +84,38 @@ func (o *ModelVersion) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ModelVersion) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ModelVersion) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ModelVersion) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ModelVersion) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -255,6 +289,9 @@ func (o ModelVersion) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_model_version_create.go b/internal/model/openapi/model_model_version_create.go index c47d9a29..ae0255d7 100644 --- a/internal/model/openapi/model_model_version_create.go +++ b/internal/model/openapi/model_model_version_create.go @@ -23,6 +23,8 @@ type ModelVersionCreate struct { RegisteredModelID string `json:"registeredModelID"` // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -102,6 +104,38 @@ func (o *ModelVersionCreate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ModelVersionCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ModelVersionCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ModelVersionCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ModelVersionCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -180,6 +214,9 @@ func (o ModelVersionCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_model_version_update.go b/internal/model/openapi/model_model_version_update.go index d9d5417a..0c35eb2a 100644 --- a/internal/model/openapi/model_model_version_update.go +++ b/internal/model/openapi/model_model_version_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ModelVersionUpdate{} type ModelVersionUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` } @@ -74,6 +76,38 @@ func (o *ModelVersionUpdate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ModelVersionUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ModelVersionUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ModelVersionUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ModelVersionUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -119,6 +153,9 @@ func (o ModelVersionUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_registered_model.go b/internal/model/openapi/model_registered_model.go index 93a726f5..e1efa2dd 100644 --- a/internal/model/openapi/model_registered_model.go +++ b/internal/model/openapi/model_registered_model.go @@ -21,6 +21,8 @@ var _ MappedNullable = &RegisteredModel{} type RegisteredModel struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -82,6 +84,38 @@ func (o *RegisteredModel) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *RegisteredModel) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *RegisteredModel) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *RegisteredModel) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *RegisteredModel) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -255,6 +289,9 @@ func (o RegisteredModel) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_registered_model_create.go b/internal/model/openapi/model_registered_model_create.go index 507cdd9f..26708045 100644 --- a/internal/model/openapi/model_registered_model_create.go +++ b/internal/model/openapi/model_registered_model_create.go @@ -21,6 +21,8 @@ var _ MappedNullable = &RegisteredModelCreate{} type RegisteredModelCreate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -76,6 +78,38 @@ func (o *RegisteredModelCreate) SetCustomProperties(v map[string]MetadataValue) o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *RegisteredModelCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *RegisteredModelCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *RegisteredModelCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *RegisteredModelCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -153,6 +187,9 @@ func (o RegisteredModelCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_registered_model_update.go b/internal/model/openapi/model_registered_model_update.go index bf0817f3..bed6283c 100644 --- a/internal/model/openapi/model_registered_model_update.go +++ b/internal/model/openapi/model_registered_model_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &RegisteredModelUpdate{} type RegisteredModelUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` } @@ -74,6 +76,38 @@ func (o *RegisteredModelUpdate) SetCustomProperties(v map[string]MetadataValue) o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *RegisteredModelUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *RegisteredModelUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *RegisteredModelUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *RegisteredModelUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -119,6 +153,9 @@ func (o RegisteredModelUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_serve_model.go b/internal/model/openapi/model_serve_model.go index 49e2ebf9..950b43c1 100644 --- a/internal/model/openapi/model_serve_model.go +++ b/internal/model/openapi/model_serve_model.go @@ -22,6 +22,8 @@ type ServeModel struct { LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -122,6 +124,38 @@ func (o *ServeModel) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ServeModel) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModel) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ServeModel) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ServeModel) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ServeModel) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -322,6 +356,9 @@ func (o ServeModel) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_serve_model_create.go b/internal/model/openapi/model_serve_model_create.go index fc7e3c9c..a740e77c 100644 --- a/internal/model/openapi/model_serve_model_create.go +++ b/internal/model/openapi/model_serve_model_create.go @@ -22,6 +22,8 @@ type ServeModelCreate struct { LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -116,6 +118,38 @@ func (o *ServeModelCreate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ServeModelCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ServeModelCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ServeModelCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ServeModelCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -220,6 +254,9 @@ func (o ServeModelCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_serve_model_update.go b/internal/model/openapi/model_serve_model_update.go index 3152ae3c..74e2996b 100644 --- a/internal/model/openapi/model_serve_model_update.go +++ b/internal/model/openapi/model_serve_model_update.go @@ -22,6 +22,8 @@ type ServeModelUpdate struct { LastKnownState *ExecutionState `json:"lastKnownState,omitempty"` // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` } @@ -111,6 +113,38 @@ func (o *ServeModelUpdate) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ServeModelUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServeModelUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ServeModelUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ServeModelUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ServeModelUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -159,6 +193,9 @@ func (o ServeModelUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_serving_environment.go b/internal/model/openapi/model_serving_environment.go index d842345d..0d93a75b 100644 --- a/internal/model/openapi/model_serving_environment.go +++ b/internal/model/openapi/model_serving_environment.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ServingEnvironment{} type ServingEnvironment struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -82,6 +84,38 @@ func (o *ServingEnvironment) SetCustomProperties(v map[string]MetadataValue) { o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ServingEnvironment) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironment) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ServingEnvironment) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ServingEnvironment) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ServingEnvironment) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -255,6 +289,9 @@ func (o ServingEnvironment) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_serving_environment_create.go b/internal/model/openapi/model_serving_environment_create.go index dbd3d5fd..faff38de 100644 --- a/internal/model/openapi/model_serving_environment_create.go +++ b/internal/model/openapi/model_serving_environment_create.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ServingEnvironmentCreate{} type ServingEnvironmentCreate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. @@ -76,6 +78,38 @@ func (o *ServingEnvironmentCreate) SetCustomProperties(v map[string]MetadataValu o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ServingEnvironmentCreate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentCreate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ServingEnvironmentCreate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ServingEnvironmentCreate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ServingEnvironmentCreate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -153,6 +187,9 @@ func (o ServingEnvironmentCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } diff --git a/internal/model/openapi/model_serving_environment_update.go b/internal/model/openapi/model_serving_environment_update.go index 4e7a52ba..3baaf117 100644 --- a/internal/model/openapi/model_serving_environment_update.go +++ b/internal/model/openapi/model_serving_environment_update.go @@ -21,6 +21,8 @@ var _ MappedNullable = &ServingEnvironmentUpdate{} type ServingEnvironmentUpdate struct { // User provided custom properties which are not defined by its type. CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` } @@ -74,6 +76,38 @@ func (o *ServingEnvironmentUpdate) SetCustomProperties(v map[string]MetadataValu o.CustomProperties = &v } +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *ServingEnvironmentUpdate) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ServingEnvironmentUpdate) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *ServingEnvironmentUpdate) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *ServingEnvironmentUpdate) SetDescription(v string) { + o.Description = &v +} + // GetExternalID returns the ExternalID field value if set, zero value otherwise. func (o *ServingEnvironmentUpdate) GetExternalID() string { if o == nil || IsNil(o.ExternalID) { @@ -119,6 +153,9 @@ func (o ServingEnvironmentUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.CustomProperties) { toSerialize["customProperties"] = o.CustomProperties } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } From c9ec94b682d8bb7eaf301ac85430427a5705bd28 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Mon, 6 Nov 2023 08:52:19 +0100 Subject: [PATCH 096/254] Update the README (#124) * Update the README * Apply suggestions from code review Co-authored-by: Matteo Mortari --------- Co-authored-by: Matteo Mortari --- README.md | 153 +++++++++++++++++++++----------------- docker-compose-local.yaml | 20 +++++ docker-compose.yaml | 19 +++++ 3 files changed, 122 insertions(+), 70 deletions(-) create mode 100644 docker-compose-local.yaml create mode 100644 docker-compose.yaml diff --git a/README.md b/README.md index d35bd4b2..2c574527 100644 --- a/README.md +++ b/README.md @@ -2,96 +2,109 @@ ![build checks status](https://github.com/opendatahub-io/model-registry/actions/workflows/build.yml/badge.svg?branch=main) -A go based server that implements a gRPC interface for [ml_metadata](https://github.com/google/ml-metadata/) library. -It adds other features on top of the functionality offered by the gRPC interface. +Model registry provides a central repository for model developers to store and manage models, versions, and artifacts metadata. A Go-based application that leverages [ml_metadata](https://github.com/google/ml-metadata/) project under the hood. + ## Pre-requisites: - go >= 1.19 - protoc v24.3 - [Protocol Buffers v24.3 Release](https://github.com/protocolbuffers/protobuf/releases/tag/v24.3) - npm >= 10.2.0 - [Installing Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) - Java >= 11.0 - python 3.9 -## Building -Run the following command to build the server binary: -``` -make build -``` -The generated binary uses spf13 cmdline args. More information on using the server can be obtained by running the command: -``` -./model-registry --help -``` + ## OpenAPI Proxy Server + +The model registry proxy server implementation follows a contract-first approach, where the contract is identified by [model-registry.yaml](api/openapi/model-registry.yaml) OpenAPI specification. + +You can also easily display the latest OpenAPI contract for model-registry in a Swagger-like editor directly from this repository; for example, [here](https://editor.swagger.io/?url=https://raw.githubusercontent.com/opendatahub-io/model-registry/main/api/openapi/model-registry.yaml). ### Starting the OpenAPI Proxy Server -Run the following command to start the OpenAPI proxy server: -``` -make run/proxy & -``` -The proxy service implements the OpenAPI defined in [model-registry.yaml](api/openapi/model-registry.yaml) to create an Open Data Hub specific REST API that stores metadata in an ml-metadata CPP server. -## Server -### Creating/Migrating Server DB -The server uses a local SQLite DB file (`metadata.sqlite.db` by default), which can be configured using the `-d` cmdline option. -The following command creates the DB: -``` -./model-registry migrate -``` -### Loading metadata library -Run the following command to load a metadata library: -``` -./model-registry migrate -m config/metadata-library -``` -Note that currently no duplicate detection is done as the implementation is a WIP proof of concept. -Running this command multiple times will create duplicate metadata types. -To clear the DB simply delete the SQLite DB file `metadata.sqlite.db`. +Run the following command to start the OpenAPI proxy server from source: -### Starting the Server -Run the following command to start the server: -``` -make run/server & -``` -## Clients -### Running Python ml-metadata test client -Before running the test client, install the required Python libraries (using a python venv, if using one) -using the command: -``` -pip install ml_metadata grpcio -``` -Run the following command to run the ml-metadata Python test client: -``` -make run/client -``` -### Running GraphQL Playground -This project includes support for a GraphiQL playground, which supports interactive query design. -It can be reached by opening the following URL in a web browser: +```shell +make run/proxy ``` -http://localhost:8080/ +The proxy service implements the OpenAPI defined in [model-registry.yaml](api/openapi/model-registry.yaml) to create an Open Data Hub specific REST API on top of the existing ml-metadata server. + +> **NOTE** The ml-metadata server must be running and accessible from the environment where model-registry starts up. + +## Model Registry Core + +The model registry core is the layer which implements the core/business logic by interacting with the underlying ml-metadata server. +It provides a model registry domain-specific [api](internal/core/api.go) that is in charge to proxy all, appropriately transformed, requests to ml-metadata using gRPC calls. + +### Model registry library + +TODO + +## Development + +### Building +Run the following command to build the server binary: + +```shell +make build ``` -Where, 8080 is the default port that the server listens on. This port can be changed with the `-p` option. -### Clean -Run the following command to clean the server binary, generated gRPC and GraphQL models, etc.: + +The generated binary uses `spf13` cmdline args. More information on using the server can be obtained by running the command: + +```shell +./model-registry --help ``` + +Run the following command to clean the server binary, generated models and etc.: + +```shell make clean ``` -## Docker Image -### Building the Docker Image -The following command builds a docker image for the server with the tag `model-registry``: + +### Testing + +Run the following command to trigger all tests: + ```shell -docker build -t model-registry . +make test ``` -Note that the first build will be longer as it downloads the build tool dependencies. -Subsequent builds will re-use the cached tools layer. -### Creating/Migrating Server DB -The following command migrates or creates a DB for the server: + +or, to see the statement coverage: + ```shell -docker run -it --user : -v :/var/db model-registry migrate -d /var/db/metadata.sqlite.db -m /config/metadata-library +make test-cover ``` -Where, `` and `` are local user and group ids on the host machine to allow volume mapping for the DB files. -And, `` is the path on the local directory writable by the `:` user. -### Running the Server -The following command starts the server: + +### Docker Image +#### Building the docker image +The following command builds a docker image for the server with the tag `model-registry`: + ```shell -docker run -d -p ::8080 --user : -v :/var/db --name server model-registry serve -n 0.0.0.0 -d /var/db/metadata.sqlite.db +docker build -t model-registry . +``` + +Note that the first build will be longer as it downloads the build tool dependencies. +Subsequent builds will re-use the cached tools layer. + +#### Running the proxy server + +> **NOTE:** ml-metadata server must be running and accessible, see more info on how to start the gRPC server in the official ml-metadata [documentation](https://github.com/google/ml-metadata). + +The following command starts the proxy server: + +```shell +docker run -d -p ::8080 --user : --name server model-registry proxy -n 0.0.0.0 ``` + Where, ``, ``, and `` are the same as in the migrate command above. And `` and `` are the local ip and port to use to expose the container's default `8080` listening port. -The server listens on `localhost` by default, hence the `-n 0.0.0.0` option allows the server port to be exposed. +The server listens on `localhost` by default, hence the `-n 0.0.0.0` option allows the server port to be exposed. + +#### Running model registry & ml-metadata + +> **NOTE:** Docker compose must be installed in your environment. + +There are two `docker-compose` files that make the startup of both model registry and ml-metadara easier, by simply running: + +```shell +docker compose -f docker-compose[-local].yaml up +``` + +The main difference between the two docker compose files is that `-local` one build the model registry from source, the other one, instead, download the `latest` pushed [quay.io](https://quay.io/repository/opendatahub/model-registry?tab=tags) image. -Once the server has started, test clients and playground can be used as described in the above sections. +When shutting down the docker compose, you might want to clean-up the SQLite db file generated by ML Metadata, for example `./test/config/ml-metadata/metadata.sqlite.db` \ No newline at end of file diff --git a/docker-compose-local.yaml b/docker-compose-local.yaml new file mode 100644 index 00000000..380624cc --- /dev/null +++ b/docker-compose-local.yaml @@ -0,0 +1,20 @@ +version: '3' +services: + ml-metadata: + image: gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0 + container_name: mlmd-server + ports: + - "8080:8080" + environment: + - METADATA_STORE_SERVER_CONFIG_FILE=/tmp/shared/conn_config.pb + volumes: + - ./test/config/ml-metadata:/tmp/shared + model-registry: + build: + context: . + dockerfile: Dockerfile + container_name: model-registry + ports: + - "8081:8080" + depends_on: + - ml-metadata \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 00000000..de19a7ee --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,19 @@ +version: '3' +services: + ml-metadata: + image: gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0 + container_name: mlmd-server + ports: + - "8080:8080" + environment: + - METADATA_STORE_SERVER_CONFIG_FILE=/tmp/shared/conn_config.pb + volumes: + - ./test/config/ml-metadata:/tmp/shared + model-registry: + image: quay.io/opendatahub/model-registry:latest + command: ["proxy"] + container_name: model-registry + ports: + - "8081:8080" + depends_on: + - ml-metadata \ No newline at end of file From b6aaaaee4aee1401820ffe64d9c0c8702f26aefc Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Mon, 6 Nov 2023 08:53:18 +0100 Subject: [PATCH 097/254] Implement core layer mapper using Goverter (#123) * goverter for openapi from/to mlmd mapping * goverter make use of openapi model wrapper * add converter tests * goverter add missing mapping * goverter add description mapping --- Makefile | 10 +- .../{converter.go => grpc_converter.gen.go} | 0 .../generated/mlmd_openapi_converter.gen.go | 108 +++++ .../generated/openapi_mlmd_converter.gen.go | 172 +++++++ internal/converter/grpc_converter.go | 2 + .../converter/mlmd_converter_util_test.go | 455 ++++++++++++++++++ internal/converter/mlmd_openapi_converter.go | 36 ++ .../converter/mlmd_openapi_converter_util.go | 135 ++++++ internal/converter/openapi_mlmd_converter.go | 50 ++ .../converter/openapi_mlmd_converter_util.go | 266 ++++++++++ internal/core/core.go | 116 ++--- internal/core/core_test.go | 202 ++++---- internal/core/mapper.go | 111 +++++ internal/core/mapper/mlmd_mapper.go | 377 --------------- internal/core/mapper/mlmd_mapper_test.go | 125 ----- 15 files changed, 1510 insertions(+), 655 deletions(-) rename internal/converter/generated/{converter.go => grpc_converter.gen.go} (100%) create mode 100755 internal/converter/generated/mlmd_openapi_converter.gen.go create mode 100755 internal/converter/generated/openapi_mlmd_converter.gen.go create mode 100644 internal/converter/mlmd_converter_util_test.go create mode 100644 internal/converter/mlmd_openapi_converter.go create mode 100644 internal/converter/mlmd_openapi_converter_util.go create mode 100644 internal/converter/openapi_mlmd_converter.go create mode 100644 internal/converter/openapi_mlmd_converter_util.go create mode 100644 internal/core/mapper.go delete mode 100644 internal/core/mapper/mlmd_mapper.go delete mode 100644 internal/core/mapper/mlmd_mapper_test.go diff --git a/Makefile b/Makefile index e205def1..0d677336 100644 --- a/Makefile +++ b/Makefile @@ -59,10 +59,10 @@ internal/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto gen/grpc: internal/ml_metadata/proto/metadata_store.pb.go internal/ml_metadata/proto/metadata_store_service.pb.go internal/converter/generated/converter.go: internal/converter/*.go - goverter -packageName generated -output ./internal/converter/generated/converter.go github.com/opendatahub-io/model-registry/internal/converter/ + goverter gen github.com/opendatahub-io/model-registry/internal/converter/ .PHONY: gen/converter -gen/converter: gen/grpc gen/graph internal/converter/generated/converter.go +gen/converter: gen/grpc internal/converter/generated/converter.go gen/graph .PHONY: gen/graph gen/graph: internal/model/graph/models_gen.go @@ -101,7 +101,7 @@ vet: .PHONY: clean clean: - rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/converter.go internal/model/openapi + rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/*.go internal/model/openapi bin/go-enum: GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 @@ -119,7 +119,7 @@ bin/golangci-lint: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.54.2 bin/goverter: - GOBIN=$(PROJECT_PATH)/bin go install github.com/jmattheis/goverter/cmd/goverter@v0.18.0 + GOBIN=$(PROJECT_PATH)/bin go install github.com/jmattheis/goverter/cmd/goverter@v1.0.0 OPENAPI_GENERATOR ?= ${PROJECT_BIN}/openapi-generator-cli NPM ?= "$(shell which npm)" @@ -151,7 +151,7 @@ build: gen vet lint go build .PHONY: gen -gen: deps gen/grpc gen/openapi gen/graph gen/converter +gen: deps gen/grpc gen/openapi gen/converter gen/graph go generate ./... .PHONY: lint diff --git a/internal/converter/generated/converter.go b/internal/converter/generated/grpc_converter.gen.go similarity index 100% rename from internal/converter/generated/converter.go rename to internal/converter/generated/grpc_converter.gen.go diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go new file mode 100755 index 00000000..a7ca2f4a --- /dev/null +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -0,0 +1,108 @@ +// Code generated by github.com/jmattheis/goverter, DO NOT EDIT. + +package generated + +import ( + "fmt" + converter "github.com/opendatahub-io/model-registry/internal/converter" + proto "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + openapi "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +type MLMDToOpenAPIConverterImpl struct{} + +func (c *MLMDToOpenAPIConverterImpl) ConvertModelArtifact(source *proto.Artifact) (*openapi.ModelArtifact, error) { + var pOpenapiModelArtifact *openapi.ModelArtifact + if source != nil { + var openapiModelArtifact openapi.ModelArtifact + mapStringOpenapiMetadataValue, err := converter.MapMLMDCustomProperties((*source).CustomProperties) + if err != nil { + return nil, err + } + openapiModelArtifact.CustomProperties = &mapStringOpenapiMetadataValue + openapiModelArtifact.Description = converter.MapDescription((*source).Properties) + var pString *string + if (*source).ExternalId != nil { + xstring := *(*source).ExternalId + pString = &xstring + } + openapiModelArtifact.ExternalID = pString + var pString2 *string + if (*source).Uri != nil { + xstring2 := *(*source).Uri + pString2 = &xstring2 + } + openapiModelArtifact.Uri = pString2 + openapiModelArtifact.State = converter.MapMLMDModelArtifactState((*source).State) + openapiModelArtifact.Name = converter.MapNameFromOwned((*source).Name) + openapiModelArtifact.Id = converter.Int64ToString((*source).Id) + openapiModelArtifact.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) + openapiModelArtifact.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + xstring3, err := converter.MapArtifactType(source) + if err != nil { + return nil, fmt.Errorf("error setting field ArtifactType: %w", err) + } + openapiModelArtifact.ArtifactType = xstring3 + openapiModelArtifact.ModelFormatName = converter.MapModelArtifactFormatName((*source).Properties) + openapiModelArtifact.Runtime = converter.MapModelArtifactRuntime((*source).Properties) + openapiModelArtifact.StorageKey = converter.MapModelArtifactStorageKey((*source).Properties) + openapiModelArtifact.StoragePath = converter.MapModelArtifactStoragePath((*source).Properties) + openapiModelArtifact.ModelFormatVersion = converter.MapModelArtifactFormatVersion((*source).Properties) + openapiModelArtifact.ServiceAccountName = converter.MapModelArtifactServiceAccountName((*source).Properties) + pOpenapiModelArtifact = &openapiModelArtifact + } + return pOpenapiModelArtifact, nil +} +func (c *MLMDToOpenAPIConverterImpl) ConvertModelVersion(source *proto.Context) (*openapi.ModelVersion, error) { + var pOpenapiModelVersion *openapi.ModelVersion + if source != nil { + var openapiModelVersion openapi.ModelVersion + mapStringOpenapiMetadataValue, err := converter.MapMLMDCustomProperties((*source).CustomProperties) + if err != nil { + return nil, err + } + openapiModelVersion.CustomProperties = &mapStringOpenapiMetadataValue + openapiModelVersion.Description = converter.MapDescription((*source).Properties) + var pString *string + if (*source).ExternalId != nil { + xstring := *(*source).ExternalId + pString = &xstring + } + openapiModelVersion.ExternalID = pString + openapiModelVersion.Name = converter.MapNameFromOwned((*source).Name) + openapiModelVersion.Id = converter.Int64ToString((*source).Id) + openapiModelVersion.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) + openapiModelVersion.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + pOpenapiModelVersion = &openapiModelVersion + } + return pOpenapiModelVersion, nil +} +func (c *MLMDToOpenAPIConverterImpl) ConvertRegisteredModel(source *proto.Context) (*openapi.RegisteredModel, error) { + var pOpenapiRegisteredModel *openapi.RegisteredModel + if source != nil { + var openapiRegisteredModel openapi.RegisteredModel + mapStringOpenapiMetadataValue, err := converter.MapMLMDCustomProperties((*source).CustomProperties) + if err != nil { + return nil, err + } + openapiRegisteredModel.CustomProperties = &mapStringOpenapiMetadataValue + openapiRegisteredModel.Description = converter.MapDescription((*source).Properties) + var pString *string + if (*source).ExternalId != nil { + xstring := *(*source).ExternalId + pString = &xstring + } + openapiRegisteredModel.ExternalID = pString + var pString2 *string + if (*source).Name != nil { + xstring2 := *(*source).Name + pString2 = &xstring2 + } + openapiRegisteredModel.Name = pString2 + openapiRegisteredModel.Id = converter.Int64ToString((*source).Id) + openapiRegisteredModel.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) + openapiRegisteredModel.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + pOpenapiRegisteredModel = &openapiRegisteredModel + } + return pOpenapiRegisteredModel, nil +} diff --git a/internal/converter/generated/openapi_mlmd_converter.gen.go b/internal/converter/generated/openapi_mlmd_converter.gen.go new file mode 100755 index 00000000..72864b5a --- /dev/null +++ b/internal/converter/generated/openapi_mlmd_converter.gen.go @@ -0,0 +1,172 @@ +// Code generated by github.com/jmattheis/goverter, DO NOT EDIT. + +package generated + +import ( + "fmt" + converter "github.com/opendatahub-io/model-registry/internal/converter" + proto "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + openapi "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +type OpenAPIToMLMDConverterImpl struct{} + +func (c *OpenAPIToMLMDConverterImpl) ConvertModelArtifact(source *converter.OpenAPIModelWrapper[openapi.ModelArtifact]) (*proto.Artifact, error) { + var pProtoArtifact *proto.Artifact + if source != nil { + var protoArtifact proto.Artifact + var pString *string + if (*source).Model != nil { + pString = (*source).Model.Id + } + pInt64, err := converter.StringToInt64(pString) + if err != nil { + return nil, fmt.Errorf("error setting field Id: %w", err) + } + protoArtifact.Id = pInt64 + protoArtifact.Name = converter.MapModelArtifactName(source) + pInt642 := (*source).TypeId + protoArtifact.TypeId = &pInt642 + protoArtifact.Type = converter.MapModelArtifactType((*source).Model) + var pString2 *string + if (*source).Model != nil { + pString2 = (*source).Model.Uri + } + var pString3 *string + if pString2 != nil { + xstring := *pString2 + pString3 = &xstring + } + protoArtifact.Uri = pString3 + var pString4 *string + if (*source).Model != nil { + pString4 = (*source).Model.ExternalID + } + var pString5 *string + if pString4 != nil { + xstring2 := *pString4 + pString5 = &xstring2 + } + protoArtifact.ExternalId = pString5 + mapStringPProtoValue, err := converter.MapModelArtifactProperties((*source).Model) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoArtifact.Properties = mapStringPProtoValue + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).Model != nil { + pMapStringOpenapiMetadataValue = (*source).Model.CustomProperties + } + mapStringPProtoValue2, err := converter.MapOpenAPICustomProperties(pMapStringOpenapiMetadataValue) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoArtifact.CustomProperties = mapStringPProtoValue2 + var pOpenapiArtifactState *openapi.ArtifactState + if (*source).Model != nil { + pOpenapiArtifactState = (*source).Model.State + } + protoArtifact.State = converter.MapOpenAPIModelArtifactState(pOpenapiArtifactState) + pProtoArtifact = &protoArtifact + } + return pProtoArtifact, nil +} +func (c *OpenAPIToMLMDConverterImpl) ConvertModelVersion(source *converter.OpenAPIModelWrapper[openapi.ModelVersion]) (*proto.Context, error) { + var pProtoContext *proto.Context + if source != nil { + var protoContext proto.Context + var pString *string + if (*source).Model != nil { + pString = (*source).Model.Id + } + pInt64, err := converter.StringToInt64(pString) + if err != nil { + return nil, fmt.Errorf("error setting field Id: %w", err) + } + protoContext.Id = pInt64 + protoContext.Name = converter.MapModelVersionName(source) + pInt642 := (*source).TypeId + protoContext.TypeId = &pInt642 + protoContext.Type = converter.MapModelVersionType((*source).Model) + var pString2 *string + if (*source).Model != nil { + pString2 = (*source).Model.ExternalID + } + var pString3 *string + if pString2 != nil { + xstring := *pString2 + pString3 = &xstring + } + protoContext.ExternalId = pString3 + mapStringPProtoValue, err := converter.MapModelVersionProperties(source) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoContext.Properties = mapStringPProtoValue + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).Model != nil { + pMapStringOpenapiMetadataValue = (*source).Model.CustomProperties + } + mapStringPProtoValue2, err := converter.MapOpenAPICustomProperties(pMapStringOpenapiMetadataValue) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoContext.CustomProperties = mapStringPProtoValue2 + pProtoContext = &protoContext + } + return pProtoContext, nil +} +func (c *OpenAPIToMLMDConverterImpl) ConvertRegisteredModel(source *converter.OpenAPIModelWrapper[openapi.RegisteredModel]) (*proto.Context, error) { + var pProtoContext *proto.Context + if source != nil { + var protoContext proto.Context + var pString *string + if (*source).Model != nil { + pString = (*source).Model.Id + } + pInt64, err := converter.StringToInt64(pString) + if err != nil { + return nil, fmt.Errorf("error setting field Id: %w", err) + } + protoContext.Id = pInt64 + var pString2 *string + if (*source).Model != nil { + pString2 = (*source).Model.Name + } + var pString3 *string + if pString2 != nil { + xstring := *pString2 + pString3 = &xstring + } + protoContext.Name = pString3 + pInt642 := (*source).TypeId + protoContext.TypeId = &pInt642 + protoContext.Type = converter.MapRegisteredModelType((*source).Model) + var pString4 *string + if (*source).Model != nil { + pString4 = (*source).Model.ExternalID + } + var pString5 *string + if pString4 != nil { + xstring2 := *pString4 + pString5 = &xstring2 + } + protoContext.ExternalId = pString5 + mapStringPProtoValue, err := converter.MapRegisteredModelProperties((*source).Model) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoContext.Properties = mapStringPProtoValue + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).Model != nil { + pMapStringOpenapiMetadataValue = (*source).Model.CustomProperties + } + mapStringPProtoValue2, err := converter.MapOpenAPICustomProperties(pMapStringOpenapiMetadataValue) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoContext.CustomProperties = mapStringPProtoValue2 + pProtoContext = &protoContext + } + return pProtoContext, nil +} diff --git a/internal/converter/grpc_converter.go b/internal/converter/grpc_converter.go index dae5ff18..29238e82 100644 --- a/internal/converter/grpc_converter.go +++ b/internal/converter/grpc_converter.go @@ -2,6 +2,7 @@ package converter import ( "fmt" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/db" "gorm.io/gorm" @@ -23,6 +24,7 @@ func SetConverterDB(db *gorm.DB) error { } // goverter:converter +// goverter:output:file ./generated/grpc_converter.gen.go // goverter:wrapErrors // goverter:matchIgnoreCase // goverter:useZeroValueOnPointerInconsistency diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go new file mode 100644 index 00000000..e4ddf882 --- /dev/null +++ b/internal/converter/mlmd_converter_util_test.go @@ -0,0 +1,455 @@ +package converter + +import ( + "encoding/base64" + "encoding/json" + "strings" + "testing" + + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/stretchr/testify/assert" + "golang.org/x/exp/maps" +) + +func setup(t *testing.T) *assert.Assertions { + return assert.New(t) +} + +func TestStringToInt64(t *testing.T) { + assertion := setup(t) + + valid := "12345" + converted, err := StringToInt64(&valid) + assertion.Nil(err) + assertion.Equal(int64(12345), *converted) + assertion.Nil(StringToInt64(nil)) +} + +func TestStringToInt64InvalidNumber(t *testing.T) { + assertion := setup(t) + + invalid := "not-a-number" + converted, err := StringToInt64(&invalid) + assertion.NotNil(err) + assertion.Nil(converted) +} + +func TestInt64ToString(t *testing.T) { + assertion := setup(t) + + valid := int64(54321) + converted := Int64ToString(&valid) + assertion.Equal("54321", *converted) + assertion.Nil(Int64ToString(nil)) +} + +func TestMetadataValueBool(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my bool" + mdValue := true + data[key] = openapi.MetadataBoolValueAsMetadataValue(&openapi.MetadataBoolValue{BoolValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueInt(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my int" + mdValue := "987" + data[key] = openapi.MetadataIntValueAsMetadataValue(&openapi.MetadataIntValue{IntValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueIntFailure(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my int" + mdValue := "not a number" + data[key] = openapi.MetadataIntValueAsMetadataValue(&openapi.MetadataIntValue{IntValue: &mdValue}) + + assertion := setup(t) + asGRPC, err := MapOpenAPICustomProperties(&data) + if err == nil { + assertion.Fail("Did not expected a converted value but an error: %v", asGRPC) + } +} + +func TestMetadataValueDouble(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my double" + mdValue := 3.1415 + data[key] = openapi.MetadataDoubleValueAsMetadataValue(&openapi.MetadataDoubleValue{DoubleValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueString(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my string" + mdValue := "Hello, World!" + data[key] = openapi.MetadataStringValueAsMetadataValue(&openapi.MetadataStringValue{StringValue: &mdValue}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueStruct(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my struct" + + myMap := make(map[string]interface{}) + myMap["name"] = "John Doe" + myMap["age"] = 47 + asJSON, err := json.Marshal(myMap) + if err != nil { + t.Error(err) + } + b64 := base64.StdEncoding.EncodeToString(asJSON) + data[key] = openapi.MetadataStructValueAsMetadataValue(&openapi.MetadataStructValue{StructValue: &b64}) + + roundTripAndAssert(t, data, key) +} + +func TestMetadataValueProtoUnsupported(t *testing.T) { + data := make(map[string]openapi.MetadataValue) + key := "my proto" + + myMap := make(map[string]interface{}) + myMap["name"] = "John Doe" + myMap["age"] = 47 + asJSON, err := json.Marshal(myMap) + if err != nil { + t.Error(err) + } + b64 := base64.StdEncoding.EncodeToString(asJSON) + typeDef := "map[string]openapi.MetadataValue" + data[key] = openapi.MetadataProtoValueAsMetadataValue(&openapi.MetadataProtoValue{ + Type: &typeDef, + ProtoValue: &b64, + }) + + assertion := setup(t) + asGRPC, err := MapOpenAPICustomProperties(&data) + if err == nil { + assertion.Fail("Did not expected a converted value but an error: %v", asGRPC) + } +} + +func roundTripAndAssert(t *testing.T, data map[string]openapi.MetadataValue, key string) { + assertion := setup(t) + + // first half + asGRPC, err := MapOpenAPICustomProperties(&data) + if err != nil { + t.Error(err) + } + assertion.Contains(maps.Keys(asGRPC), key) + + // second half + unmarshall, err := MapMLMDCustomProperties(asGRPC) + if err != nil { + t.Error(err) + } + assertion.Equal(data, unmarshall, "result of round-trip shall be equal to original data") +} + +func TestPrefixWhenOwned(t *testing.T) { + assertion := setup(t) + + owner := "owner" + entity := "name" + assertion.Equal("owner:name", PrefixWhenOwned(&owner, entity)) +} + +func TestPrefixWhenOwnedWithoutOwner(t *testing.T) { + assertion := setup(t) + + entity := "name" + prefixed := PrefixWhenOwned(nil, entity) + assertion.Equal(2, len(strings.Split(prefixed, ":"))) + assertion.Equal("name", strings.Split(prefixed, ":")[1]) +} + +func TestMapRegisteredModelProperties(t *testing.T) { + assertion := setup(t) + + props, err := MapRegisteredModelProperties(&openapi.RegisteredModel{}) + assertion.Nil(err) + assertion.Equal(0, len(props)) +} + +func TestMapRegisteredModelType(t *testing.T) { + assertion := setup(t) + + typeName := MapRegisteredModelType(&openapi.RegisteredModel{}) + assertion.NotNil(typeName) + assertion.Equal(RegisteredModelTypeName, *typeName) +} + +func TestMapModelVersionProperties(t *testing.T) { + assertion := setup(t) + + props, err := MapModelVersionProperties(&OpenAPIModelWrapper[openapi.ModelVersion]{ + TypeId: 123, + ParentResourceId: of("123"), + ModelName: of("MyModel"), + Model: &openapi.ModelVersion{ + Name: of("v1"), + }, + }) + assertion.Nil(err) + assertion.Equal(3, len(props)) + // TODO check all 3 props +} + +func TestMapModelVersionType(t *testing.T) { + assertion := setup(t) + + typeName := MapModelVersionType(&openapi.ModelVersion{}) + assertion.NotNil(typeName) + assertion.Equal(ModelVersionTypeName, *typeName) +} + +func TestMapModelVersionName(t *testing.T) { + assertion := setup(t) + + name := MapModelVersionName(&OpenAPIModelWrapper[openapi.ModelVersion]{ + TypeId: 123, + ParentResourceId: of("123"), + ModelName: of("MyModel"), + Model: &openapi.ModelVersion{ + Name: of("v1"), + }, + }) + assertion.NotNil(name) + assertion.Equal("123:v1", *name) +} + +func TestMapModelArtifactProperties(t *testing.T) { + assertion := setup(t) + + props, err := MapModelArtifactProperties(&openapi.ModelArtifact{ + Name: of("v1"), + ModelFormatName: of("sklearn"), + ModelFormatVersion: of("1.0"), + Runtime: of("my-runtime"), + StorageKey: of("storage-key"), + StoragePath: of("storage-path"), + ServiceAccountName: of("service-account-name"), + }) + assertion.Nil(err) + assertion.Equal(6, len(props)) + assertion.Equal("sklearn", props["model_format_name"].GetStringValue()) + assertion.Equal("1.0", props["model_format_version"].GetStringValue()) + assertion.Equal("my-runtime", props["runtime"].GetStringValue()) + assertion.Equal("storage-key", props["storage_key"].GetStringValue()) + assertion.Equal("storage-path", props["storage_path"].GetStringValue()) + assertion.Equal("service-account-name", props["service_account_name"].GetStringValue()) + + props, err = MapModelArtifactProperties(&openapi.ModelArtifact{ + Name: of("v1"), + }) + assertion.Nil(err) + assertion.Equal(0, len(props)) +} + +func TestMapModelArtifactType(t *testing.T) { + assertion := setup(t) + + typeName := MapModelArtifactType(&openapi.ModelArtifact{}) + assertion.NotNil(typeName) + assertion.Equal(ModelArtifactTypeName, *typeName) +} + +func TestMapModelArtifactName(t *testing.T) { + assertion := setup(t) + + name := MapModelArtifactName(&OpenAPIModelWrapper[openapi.ModelArtifact]{ + TypeId: 123, + ParentResourceId: of("parent"), + Model: &openapi.ModelArtifact{ + Name: of("v1"), + }, + }) + assertion.NotNil(name) + assertion.Equal("parent:v1", *name) + + name = MapModelArtifactName(&OpenAPIModelWrapper[openapi.ModelArtifact]{ + TypeId: 123, + ParentResourceId: of("parent"), + Model: &openapi.ModelArtifact{ + Name: nil, + }, + }) + assertion.NotNil(name) + assertion.Regexp("parent:.*", *name) + + name = MapModelArtifactName(&OpenAPIModelWrapper[openapi.ModelArtifact]{ + TypeId: 123, + Model: &openapi.ModelArtifact{ + Name: of("v1"), + }, + }) + assertion.NotNil(name) + assertion.Regexp(".*:v1", *name) +} + +func TestMapOpenAPIModelArtifactState(t *testing.T) { + assertion := setup(t) + + state := MapOpenAPIModelArtifactState(of(openapi.ARTIFACTSTATE_LIVE)) + assertion.NotNil(state) + assertion.Equal(string(openapi.ARTIFACTSTATE_LIVE), state.String()) + + state = MapOpenAPIModelArtifactState(nil) + assertion.Nil(state) +} + +func TestMapStringPropertyWithMissingKey(t *testing.T) { + assertion := setup(t) + + notPresent := MapStringProperty(map[string]*proto.Value{}, "not_present") + + assertion.Nil(notPresent) +} + +func TestMapDescription(t *testing.T) { + assertion := setup(t) + + extracted := MapDescription(map[string]*proto.Value{ + "description": { + Value: &proto.Value_StringValue{ + StringValue: "my-description", + }, + }, + }) + + assertion.Equal("my-description", *extracted) +} + +func TestMapModelArtifactRuntime(t *testing.T) { + assertion := setup(t) + + extracted := MapModelArtifactRuntime(map[string]*proto.Value{ + "runtime": { + Value: &proto.Value_StringValue{ + StringValue: "my-runtime", + }, + }, + }) + + assertion.Equal("my-runtime", *extracted) +} + +func TestMapModelArtifactFormatName(t *testing.T) { + assertion := setup(t) + + extracted := MapModelArtifactFormatName(map[string]*proto.Value{ + "model_format_name": { + Value: &proto.Value_StringValue{ + StringValue: "my-name", + }, + }, + }) + + assertion.Equal("my-name", *extracted) +} + +func TestMapModelArtifactFormatVersion(t *testing.T) { + assertion := setup(t) + + extracted := MapModelArtifactFormatVersion(map[string]*proto.Value{ + "model_format_version": { + Value: &proto.Value_StringValue{ + StringValue: "my-version", + }, + }, + }) + + assertion.Equal("my-version", *extracted) +} + +func TestMapModelArtifactStorageKey(t *testing.T) { + assertion := setup(t) + + extracted := MapModelArtifactStorageKey(map[string]*proto.Value{ + "storage_key": { + Value: &proto.Value_StringValue{ + StringValue: "my-key", + }, + }, + }) + + assertion.Equal("my-key", *extracted) +} + +func TestMapModelArtifactStoragePath(t *testing.T) { + assertion := setup(t) + + extracted := MapModelArtifactStoragePath(map[string]*proto.Value{ + "storage_path": { + Value: &proto.Value_StringValue{ + StringValue: "my-path", + }, + }, + }) + + assertion.Equal("my-path", *extracted) +} + +func TestMapModelArtifactServiceAccountName(t *testing.T) { + assertion := setup(t) + + extracted := MapModelArtifactServiceAccountName(map[string]*proto.Value{ + "service_account_name": { + Value: &proto.Value_StringValue{ + StringValue: "my-account", + }, + }, + }) + + assertion.Equal("my-account", *extracted) +} + +func TestMapNameFromOwned(t *testing.T) { + assertion := setup(t) + + name := MapNameFromOwned(of("prefix:name")) + assertion.Equal("name", *name) + + name = MapNameFromOwned(of("name")) + assertion.Equal("name", *name) + + name = MapNameFromOwned(of("prefix:name:postfix")) + assertion.Equal("name", *name) + + name = MapNameFromOwned(nil) + assertion.Nil(name) +} + +func TestMapArtifactType(t *testing.T) { + assertion := setup(t) + + artifactType, err := MapArtifactType(&proto.Artifact{ + Type: of(ModelArtifactTypeName), + }) + assertion.Nil(err) + assertion.Equal("model-artifact", artifactType) + + artifactType, err = MapArtifactType(&proto.Artifact{ + Type: of("Invalid"), + }) + assertion.NotNil(err) + assertion.Equal("", artifactType) +} + +func TestMapMLMDModelArtifactState(t *testing.T) { + assertion := setup(t) + + artifactState := MapMLMDModelArtifactState(proto.Artifact_LIVE.Enum()) + assertion.NotNil(artifactState) + assertion.Equal("LIVE", string(*artifactState)) + + artifactState = MapMLMDModelArtifactState(nil) + assertion.Nil(artifactState) +} diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go new file mode 100644 index 00000000..a753a538 --- /dev/null +++ b/internal/converter/mlmd_openapi_converter.go @@ -0,0 +1,36 @@ +package converter + +import ( + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +// goverter:converter +// goverter:output:file ./generated/mlmd_openapi_converter.gen.go +// goverter:wrapErrors +// goverter:matchIgnoreCase +// goverter:useZeroValueOnPointerInconsistency +// goverter:extend Int64ToString +// goverter:extend StringToInt64 +// goverter:extend MapMLMDCustomProperties +type MLMDToOpenAPIConverter interface { + // goverter:map Properties Description | MapDescription + ConvertRegisteredModel(source *proto.Context) (*openapi.RegisteredModel, error) + + // goverter:map Name | MapNameFromOwned + // goverter:map Properties Description | MapDescription + ConvertModelVersion(source *proto.Context) (*openapi.ModelVersion, error) + + // TODO: map actually ignored properties from Artifact.Properties + // goverter:map Name | MapNameFromOwned + // goverter:map . ArtifactType | MapArtifactType + // goverter:map State | MapMLMDModelArtifactState + // goverter:map Properties Description | MapDescription + // goverter:map Properties Runtime | MapModelArtifactRuntime + // goverter:map Properties ModelFormatName | MapModelArtifactFormatName + // goverter:map Properties ModelFormatVersion | MapModelArtifactFormatVersion + // goverter:map Properties StorageKey | MapModelArtifactStorageKey + // goverter:map Properties StoragePath | MapModelArtifactStoragePath + // goverter:map Properties ServiceAccountName | MapModelArtifactServiceAccountName + ConvertModelArtifact(source *proto.Artifact) (*openapi.ModelArtifact, error) +} diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go new file mode 100644 index 00000000..9001af4e --- /dev/null +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -0,0 +1,135 @@ +package converter + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strings" + + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +// MapMLMDCustomProperties maps MLMD custom properties model to OpenAPI one +func MapMLMDCustomProperties(source map[string]*proto.Value) (map[string]openapi.MetadataValue, error) { + data := make(map[string]openapi.MetadataValue) + + for key, v := range source { + // data[key] = v.Value + customValue := openapi.MetadataValue{} + + switch typedValue := v.Value.(type) { + case *proto.Value_BoolValue: + customValue.MetadataBoolValue = &openapi.MetadataBoolValue{ + BoolValue: &typedValue.BoolValue, + } + case *proto.Value_IntValue: + customValue.MetadataIntValue = &openapi.MetadataIntValue{ + IntValue: Int64ToString(&typedValue.IntValue), + } + case *proto.Value_DoubleValue: + customValue.MetadataDoubleValue = &openapi.MetadataDoubleValue{ + DoubleValue: &typedValue.DoubleValue, + } + case *proto.Value_StringValue: + customValue.MetadataStringValue = &openapi.MetadataStringValue{ + StringValue: &typedValue.StringValue, + } + case *proto.Value_StructValue: + sv := typedValue.StructValue + asMap := sv.AsMap() + asJSON, err := json.Marshal(asMap) + if err != nil { + return nil, err + } + b64 := base64.StdEncoding.EncodeToString(asJSON) + customValue.MetadataStructValue = &openapi.MetadataStructValue{ + StructValue: &b64, + } + default: + return nil, fmt.Errorf("type mapping not found for %s:%v", key, v) + } + + data[key] = customValue + } + + return data, nil +} + +// MapNameFromOwned derive the entity name from the mlmd fullname +// for owned entity such as ModelVersion +// for potentially owned entity such as ModelArtifact +func MapNameFromOwned(source *string) *string { + if source == nil { + return nil + } + + exploded := strings.Split(*source, ":") + if len(exploded) == 1 { + return source + } + return &exploded[1] +} + +// REGISTERED MODEL + +// MODEL VERSION + +// MODEL ARTIFACT + +func MapArtifactType(source *proto.Artifact) (string, error) { + if *source.Type == ModelArtifactTypeName { + return "model-artifact", nil + } + return "", fmt.Errorf("invalid artifact type found") +} + +func MapMLMDModelArtifactState(source *proto.Artifact_State) *openapi.ArtifactState { + if source == nil { + return nil + } + + state := source.String() + return (*openapi.ArtifactState)(&state) +} + +// MapStringProperty maps proto.Artifact property to specific ModelArtifact string field +func MapStringProperty(properties map[string]*proto.Value, key string) *string { + val, ok := properties[key] + if ok { + res := val.GetStringValue() + if res != "" { + return &res + } + } + + return nil +} + +func MapDescription(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "description") +} + +func MapModelArtifactRuntime(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "runtime") +} + +func MapModelArtifactFormatName(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "model_format_name") +} + +func MapModelArtifactFormatVersion(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "model_format_version") +} + +func MapModelArtifactStorageKey(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "storage_key") +} + +func MapModelArtifactStoragePath(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "storage_path") +} + +func MapModelArtifactServiceAccountName(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "service_account_name") +} diff --git a/internal/converter/openapi_mlmd_converter.go b/internal/converter/openapi_mlmd_converter.go new file mode 100644 index 00000000..7aa905cf --- /dev/null +++ b/internal/converter/openapi_mlmd_converter.go @@ -0,0 +1,50 @@ +package converter + +import ( + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +const ( + RegisteredModelTypeName = "odh.RegisteredModel" + ModelVersionTypeName = "odh.ModelVersion" + ModelArtifactTypeName = "odh.ModelArtifact" +) + +type OpenAPIModelWrapper[M openapi.RegisteredModel | openapi.ModelVersion | openapi.ModelArtifact] struct { + TypeId int64 + Model *M + ParentResourceId *string // optional parent id + ModelName *string // optional registered model name +} + +// goverter:converter +// goverter:output:file ./generated/openapi_mlmd_converter.gen.go +// goverter:wrapErrors +// goverter:matchIgnoreCase +// goverter:useZeroValueOnPointerInconsistency +// goverter:extend Int64ToString +// goverter:extend StringToInt64 +// goverter:extend MapOpenAPICustomProperties +type OpenAPIToMLMDConverter interface { + // goverter:autoMap Model + // goverter:map Model Type | MapRegisteredModelType + // goverter:map Model Properties | MapRegisteredModelProperties + // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertRegisteredModel(source *OpenAPIModelWrapper[openapi.RegisteredModel]) (*proto.Context, error) + + // goverter:autoMap Model + // goverter:map . Name | MapModelVersionName + // goverter:map Model Type | MapModelVersionType + // goverter:map . Properties | MapModelVersionProperties + // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertModelVersion(source *OpenAPIModelWrapper[openapi.ModelVersion]) (*proto.Context, error) + + // goverter:autoMap Model + // goverter:map . Name | MapModelArtifactName + // goverter:map Model Type | MapModelArtifactType + // goverter:map Model Properties | MapModelArtifactProperties + // goverter:map Model.State State | MapOpenAPIModelArtifactState + // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertModelArtifact(source *OpenAPIModelWrapper[openapi.ModelArtifact]) (*proto.Artifact, error) +} diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go new file mode 100644 index 00000000..a2348d49 --- /dev/null +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -0,0 +1,266 @@ +package converter + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "strconv" + + "github.com/google/uuid" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" + "google.golang.org/protobuf/types/known/structpb" +) + +// StringToInt64 converts string-based id to int64 if numeric, otherwise return error +func StringToInt64(id *string) (*int64, error) { + if id == nil { + return nil, nil + } + + idAsInt, err := strconv.Atoi(*id) + if err != nil { + return nil, err + } + + idInt64 := int64(idAsInt) + return &idInt64, nil +} + +// Int64ToString converts numeric id to string-based one +func Int64ToString(id *int64) *string { + if id == nil { + return nil + } + + idAsString := strconv.FormatInt(*id, 10) + return &idAsString +} + +// MapOpenAPICustomProperties maps OpenAPI custom properties model to MLMD one +func MapOpenAPICustomProperties(source *map[string]openapi.MetadataValue) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + + if source != nil { + for key, v := range *source { + value := proto.Value{} + + switch { + // bool value + case v.MetadataBoolValue != nil: + value.Value = &proto.Value_BoolValue{BoolValue: *v.MetadataBoolValue.BoolValue} + // int value + case v.MetadataIntValue != nil: + intValue, err := StringToInt64(v.MetadataIntValue.IntValue) + if err != nil { + return nil, fmt.Errorf("unable to decode as int64 %w for key %s", err, key) + } + value.Value = &proto.Value_IntValue{IntValue: *intValue} + // double value + case v.MetadataDoubleValue != nil: + value.Value = &proto.Value_DoubleValue{DoubleValue: *v.MetadataDoubleValue.DoubleValue} + // string value + case v.MetadataStringValue != nil: + value.Value = &proto.Value_StringValue{StringValue: *v.MetadataStringValue.StringValue} + // struct value + case v.MetadataStructValue != nil: + data, err := base64.StdEncoding.DecodeString(*v.MetadataStructValue.StructValue) + if err != nil { + return nil, fmt.Errorf("unable to decode %w for key %s", err, key) + } + var asMap map[string]interface{} + err = json.Unmarshal(data, &asMap) + if err != nil { + return nil, fmt.Errorf("unable to decode %w for key %s", err, key) + } + asStruct, err := structpb.NewStruct(asMap) + if err != nil { + return nil, fmt.Errorf("unable to decode %w for key %s", err, key) + } + value.Value = &proto.Value_StructValue{ + StructValue: asStruct, + } + default: + return nil, fmt.Errorf("type mapping not found for %s:%v", key, v) + } + + props[key] = &value + } + } + + return props, nil +} + +// PrefixWhenOwned compose the mlmd fullname by using ownerId as prefix +// For owned entity such as ModelVersion +// for potentially owned entity such as ModelArtifact +func PrefixWhenOwned(ownerId *string, entityName string) string { + var prefix string + if ownerId != nil { + prefix = *ownerId + } else { + prefix = uuid.New().String() + } + prefixedName := fmt.Sprintf("%s:%s", prefix, entityName) + return prefixedName +} + +// REGISTERED MODEL + +// MapRegisteredModelProperties maps RegisteredModel fields to specific MLMD properties +func MapRegisteredModelProperties(source *openapi.RegisteredModel) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + if source != nil { + if source.Description != nil { + props["description"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Description, + }, + } + } + } + return props, nil +} + +// MapRegisteredModelType returnd RegisteredModel corresponding MLMD context type +func MapRegisteredModelType(_ *openapi.RegisteredModel) *string { + return of(RegisteredModelTypeName) +} + +// MODEL VERSION + +// MapModelVersionProperties maps ModelVersion fields to specific MLMD properties +func MapModelVersionProperties(source *OpenAPIModelWrapper[openapi.ModelVersion]) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + if source != nil { + if (*source.Model).Description != nil { + props["description"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *(*source.Model).Description, + }, + } + } + if (*source).ModelName != nil { + props["model_name"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *(*source).ModelName, + }, + } + } + props["version"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *(*source.Model).Name, + }, + } + // TODO: not available for now + props["author"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: "", + }, + } + } + return props, nil +} + +// MapModelVersionType returnd ModelVersion corresponding MLMD context type +func MapModelVersionType(_ *openapi.ModelVersion) *string { + return of(ModelVersionTypeName) +} + +// MapModelVersionName maps the user-provided name into MLMD one, i.e., prefixing it with +// either the parent resource id or a generated uuid +func MapModelVersionName(source *OpenAPIModelWrapper[openapi.ModelVersion]) *string { + return of(PrefixWhenOwned(source.ParentResourceId, *(*source).Model.Name)) +} + +// MODEL ARTIFACT + +// MapModelArtifactProperties maps ModelArtifact fields to specific MLMD properties +func MapModelArtifactProperties(source *openapi.ModelArtifact) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + if source != nil { + if source.Description != nil { + props["description"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Description, + }, + } + } + if source.Runtime != nil { + props["runtime"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Runtime, + }, + } + } + if source.ModelFormatName != nil { + props["model_format_name"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.ModelFormatName, + }, + } + } + if source.ModelFormatVersion != nil { + props["model_format_version"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.ModelFormatVersion, + }, + } + } + if source.StorageKey != nil { + props["storage_key"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.StorageKey, + }, + } + } + if source.StoragePath != nil { + props["storage_path"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.StoragePath, + }, + } + } + if source.ServiceAccountName != nil { + props["service_account_name"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.ServiceAccountName, + }, + } + } + } + return props, nil +} + +// MapModelArtifactType returnd ModelArtifact corresponding MLMD context type +func MapModelArtifactType(_ *openapi.ModelArtifact) *string { + return of(ModelArtifactTypeName) +} + +// MapModelArtifactName maps the user-provided name into MLMD one, i.e., prefixing it with +// either the parent resource id or a generated uuid. If not provided, autogenerate the name +// itself +func MapModelArtifactName(source *OpenAPIModelWrapper[openapi.ModelArtifact]) *string { + // openapi.Artifact is defined with optional name, so build arbitrary name for this artifact if missing + var artifactName string + if (*source).Model.Name != nil { + artifactName = *(*source).Model.Name + } else { + artifactName = uuid.New().String() + } + return of(PrefixWhenOwned(source.ParentResourceId, artifactName)) +} + +func MapOpenAPIModelArtifactState(source *openapi.ArtifactState) *proto.Artifact_State { + if source == nil { + return nil + } + + state := (proto.Artifact_State)(proto.Artifact_State_value[string(*source)]) + return &state +} + +// of returns a pointer to the provided literal/const input +func of[E any](e E) *E { + return &e +} diff --git a/internal/core/core.go b/internal/core/core.go index 29fce80b..8271cd29 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -3,25 +3,24 @@ package core import ( "context" "fmt" - "log" "github.com/golang/glog" - "github.com/opendatahub-io/model-registry/internal/core/mapper" + "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" "google.golang.org/grpc" ) var ( - RegisteredModelTypeName = "odh.RegisteredModel" - ModelVersionTypeName = "odh.ModelVersion" - ModelArtifactTypeName = "odh.ModelArtifact" + registeredModelTypeName = of(converter.RegisteredModelTypeName) + modelVersionTypeName = of(converter.ModelVersionTypeName) + modelArtifactTypeName = of(converter.ModelArtifactTypeName) ) // modelRegistryService is the core library of the model registry type modelRegistryService struct { mlmdClient proto.MetadataStoreServiceClient - mapper *mapper.Mapper + mapper *Mapper } // NewModelRegistryService create a fresh instance of ModelRegistryService, taking care of setting up needed MLMD Types @@ -33,47 +32,57 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err registeredModelReq := proto.PutContextTypeRequest{ ContextType: &proto.ContextType{ - Name: &RegisteredModelTypeName, + Name: registeredModelTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + }, }, } modelVersionReq := proto.PutContextTypeRequest{ ContextType: &proto.ContextType{ - Name: &ModelVersionTypeName, + Name: of(converter.ModelVersionTypeName), Properties: map[string]proto.PropertyType{ - "model_name": proto.PropertyType_STRING, - "version": proto.PropertyType_STRING, - "author": proto.PropertyType_STRING, + "description": proto.PropertyType_STRING, + "model_name": proto.PropertyType_STRING, + "version": proto.PropertyType_STRING, + "author": proto.PropertyType_STRING, }, }, } modelArtifactReq := proto.PutArtifactTypeRequest{ ArtifactType: &proto.ArtifactType{ - Name: &ModelArtifactTypeName, + Name: modelArtifactTypeName, Properties: map[string]proto.PropertyType{ - "model_format": proto.PropertyType_STRING, + "description": proto.PropertyType_STRING, + "runtime": proto.PropertyType_STRING, + "model_format_name": proto.PropertyType_STRING, + "model_format_version": proto.PropertyType_STRING, + "storage_key": proto.PropertyType_STRING, + "storage_path": proto.PropertyType_STRING, + "service_account_name": proto.PropertyType_STRING, }, }, } registeredModelResp, err := client.PutContextType(context.Background(), ®isteredModelReq) if err != nil { - log.Fatalf("Error setting up context type %s: %v", RegisteredModelTypeName, err) + glog.Fatalf("Error setting up context type %s: %v", registeredModelTypeName, err) } modelVersionResp, err := client.PutContextType(context.Background(), &modelVersionReq) if err != nil { - log.Fatalf("Error setting up context type %s: %v", ModelVersionTypeName, err) + glog.Fatalf("Error setting up context type %s: %v", modelVersionTypeName, err) } modelArtifactResp, err := client.PutArtifactType(context.Background(), &modelArtifactReq) if err != nil { - log.Fatalf("Error setting up artifact type %s: %v", ModelArtifactTypeName, err) + glog.Fatalf("Error setting up artifact type %s: %v", modelArtifactTypeName, err) } return &modelRegistryService{ mlmdClient: client, - mapper: mapper.NewMapper(registeredModelResp.GetTypeId(), modelVersionResp.GetTypeId(), modelArtifactResp.GetTypeId()), + mapper: NewMapper(registeredModelResp.GetTypeId(), modelVersionResp.GetTypeId(), modelArtifactResp.GetTypeId()), }, nil } @@ -114,7 +123,7 @@ func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi return nil, err } - idAsString := mapper.IdToString(modelCtxResp.ContextIds[0]) + idAsString := converter.Int64ToString(&modelCtxResp.ContextIds[0]) model, err := serv.GetRegisteredModelById(*idAsString) if err != nil { return nil, err @@ -126,7 +135,7 @@ func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) { glog.Info("Getting registered model %s", id) - idAsInt, err := mapper.IdToInt64(id) + idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err } @@ -157,7 +166,7 @@ func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.Re func (serv *modelRegistryService) getRegisteredModelByVersionId(id string) (*openapi.RegisteredModel, error) { glog.Info("Getting registered model for model version %s", id) - idAsInt, err := mapper.IdToInt64(id) + idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err } @@ -198,7 +207,7 @@ func (serv *modelRegistryService) GetRegisteredModelByParams(name *string, exter } getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ - TypeName: &RegisteredModelTypeName, + TypeName: registeredModelTypeName, Options: &proto.ListOperationOptions{ FilterQuery: &filterQuery, }, @@ -224,7 +233,7 @@ func (serv *modelRegistryService) GetRegisteredModels(listOptions ListOptions) ( return nil, err } contextsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ - TypeName: &RegisteredModelTypeName, + TypeName: registeredModelTypeName, Options: listOperationOptions, }) if err != nil { @@ -279,11 +288,6 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model } } - registeredModelId, err := mapper.IdToInt64(*registeredModel.Id) - if err != nil { - return nil, err - } - // if already existing assure the name is the same if existing != nil && modelVersion.Name == nil { // user did not provide it @@ -291,7 +295,7 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model modelVersion.Name = existing.Name } - modelCtx, err := serv.mapper.MapFromModelVersion(modelVersion, *registeredModelId, registeredModel.Name) + modelCtx, err := serv.mapper.MapFromModelVersion(modelVersion, *registeredModel.Id, registeredModel.Name) if err != nil { return nil, err } @@ -307,6 +311,11 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model modelId := &modelCtxResp.ContextIds[0] if modelVersion.Id == nil { + registeredModelId, err := converter.StringToInt64(registeredModel.Id) + if err != nil { + return nil, err + } + _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ ParentContexts: []*proto.ParentContext{{ ChildId: modelId, @@ -318,7 +327,7 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model } } - idAsString := mapper.IdToString(*modelId) + idAsString := converter.Int64ToString(modelId) model, err := serv.GetModelVersionById(*idAsString) if err != nil { return nil, err @@ -328,7 +337,7 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model } func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.ModelVersion, error) { - idAsInt, err := mapper.IdToInt64(id) + idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err } @@ -359,7 +368,7 @@ func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.Model func (serv *modelRegistryService) getModelVersionByArtifactId(id string) (*openapi.ModelVersion, error) { glog.Info("Getting model version for model artifact %s", id) - idAsInt, err := mapper.IdToInt64(id) + idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err } @@ -390,11 +399,7 @@ func (serv *modelRegistryService) getModelVersionByArtifactId(id string) (*opena func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) { filterQuery := "" if versionName != nil && parentResourceId != nil { - idAsInt, err := mapper.IdToInt64(*parentResourceId) - if err != nil { - return nil, err - } - filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned(idAsInt, *versionName)) + filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *versionName)) } else if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) } else { @@ -402,7 +407,7 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p } getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ - TypeName: &ModelVersionTypeName, + TypeName: modelVersionTypeName, Options: &proto.ListOperationOptions{ FilterQuery: &filterQuery, }, @@ -434,7 +439,7 @@ func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, pare } contextsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ - TypeName: &ModelVersionTypeName, + TypeName: modelVersionTypeName, Options: listOperationOptions, }) if err != nil { @@ -488,11 +493,6 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } } - modelVersionId, err := mapper.IdToInt64(*parentResourceId) - if err != nil { - return nil, err - } - // if already existing assure the name is the same if existing != nil { if modelArtifact.Name == nil { @@ -502,7 +502,10 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } } - artifact := serv.mapper.MapFromModelArtifact(*modelArtifact, modelVersionId) + artifact, err := serv.mapper.MapFromModelArtifact(modelArtifact, parentResourceId) + if err != nil { + return nil, err + } artifactsResp, err := serv.mlmdClient.PutArtifacts(context.Background(), &proto.PutArtifactsRequest{ Artifacts: []*proto.Artifact{artifact}, @@ -513,6 +516,10 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod // add explicit association between artifacts and model version if parentResourceId != nil && modelArtifact.Id == nil { + modelVersionId, err := converter.StringToInt64(parentResourceId) + if err != nil { + return nil, err + } attributions := []*proto.Attribution{} for _, a := range artifactsResp.ArtifactIds { attributions = append(attributions, &proto.Attribution{ @@ -529,7 +536,7 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } } - idAsString := mapper.IdToString(artifactsResp.ArtifactIds[0]) + idAsString := converter.Int64ToString(&artifactsResp.ArtifactIds[0]) mapped, err := serv.GetModelArtifactById(*idAsString) if err != nil { return nil, err @@ -538,7 +545,7 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } func (serv *modelRegistryService) GetModelArtifactById(id string) (*openapi.ModelArtifact, error) { - idAsInt, err := mapper.IdToInt64(id) + idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err } @@ -573,17 +580,13 @@ func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) } else if artifactName != nil && parentResourceId != nil { - idAsInt, err := mapper.IdToInt64(*parentResourceId) - if err != nil { - return nil, err - } - filterQuery = fmt.Sprintf("name = \"%s\"", mapper.PrefixWhenOwned(idAsInt, *artifactName)) + filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *artifactName)) } else { return nil, fmt.Errorf("invalid parameters call, supply either (artifactName and parentResourceId), or externalId") } artifactsResponse, err := serv.mlmdClient.GetArtifactsByType(context.Background(), &proto.GetArtifactsByTypeRequest{ - TypeName: &ModelArtifactTypeName, + TypeName: modelArtifactTypeName, Options: &proto.ListOperationOptions{ FilterQuery: &filterQuery, }, @@ -613,7 +616,7 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, par var artifacts []*proto.Artifact var nextPageToken *string if parentResourceId != nil { - ctxId, err := mapper.IdToInt64(*parentResourceId) + ctxId, err := converter.StringToInt64(parentResourceId) if err != nil { return nil, err } @@ -628,7 +631,7 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, par nextPageToken = artifactsResp.NextPageToken } else { artifactsResp, err := serv.mlmdClient.GetArtifactsByType(context.Background(), &proto.GetArtifactsByTypeRequest{ - TypeName: &ModelArtifactTypeName, + TypeName: modelArtifactTypeName, Options: listOperationOptions, }) if err != nil { @@ -655,3 +658,8 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, par } return &toReturn, nil } + +// of returns a pointer to the provided literal/const input +func of[E any](e E) *E { + return &e +} diff --git a/internal/core/core_test.go b/internal/core/core_test.go index 29e45821..c2f4073b 100644 --- a/internal/core/core_test.go +++ b/internal/core/core_test.go @@ -1,12 +1,11 @@ -package core_test +package core import ( "context" "fmt" "testing" - "github.com/opendatahub-io/model-registry/internal/core" - "github.com/opendatahub-io/model-registry/internal/core/mapper" + "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" "github.com/opendatahub-io/model-registry/internal/testutils" @@ -20,18 +19,21 @@ var ( ascOrderDirection string descOrderDirection string // registered models - modelName string - modelExternalId string - owner string + modelName string + modelDescription string + modelExternalId string + owner string // model version - modelVersionName string - versionExternalId string - author string + modelVersionName string + modelVersionDescription string + versionExternalId string + author string // model artifact - artifactName string - artifactExtId string - artifactState string - artifactUri string + artifactName string + artifactDescription string + artifactExtId string + artifactState string + artifactUri string ) func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { @@ -39,12 +41,15 @@ func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataSt ascOrderDirection = "ASC" descOrderDirection = "DESC" modelName = "MyAwesomeModel" + modelDescription = "reg model description" modelExternalId = "org.myawesomemodel" owner = "owner" modelVersionName = "v1" + modelVersionDescription = "model version description" versionExternalId = "org.myawesomemodel@v1" author = "author1" artifactName = "Pickle model" + artifactDescription = "artifact description" artifactExtId = "org.myawesomemodel@v1:pickle" artifactState = "LIVE" artifactUri = "path/to/model/v1" @@ -54,17 +59,18 @@ func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataSt } // initialize model registry service and assert no error is thrown -func initModelRegistryService(assertion *assert.Assertions, conn *grpc.ClientConn) core.ModelRegistryApi { - service, err := core.NewModelRegistryService(conn) +func initModelRegistryService(assertion *assert.Assertions, conn *grpc.ClientConn) ModelRegistryApi { + service, err := NewModelRegistryService(conn) assertion.Nilf(err, "error creating core service: %v", err) return service } // utility function that register a new simple model and return its ID -func registerModel(assertion *assert.Assertions, service core.ModelRegistryApi, overrideModelName *string, overrideExternalId *string) string { +func registerModel(assertion *assert.Assertions, service ModelRegistryApi, overrideModelName *string, overrideExternalId *string) string { registeredModel := &openapi.RegisteredModel{ - Name: &modelName, - ExternalID: &modelExternalId, + Name: &modelName, + ExternalID: &modelExternalId, + Description: &modelDescription, CustomProperties: &map[string]openapi.MetadataValue{ "owner": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -92,7 +98,7 @@ func registerModel(assertion *assert.Assertions, service core.ModelRegistryApi, // utility function that register a new simple model and return its ID func registerModelVersion( assertion *assert.Assertions, - service core.ModelRegistryApi, + service ModelRegistryApi, overrideModelName *string, overrideExternalId *string, overrideVersionName *string, @@ -101,8 +107,9 @@ func registerModelVersion( registeredModelId := registerModel(assertion, service, overrideModelName, overrideExternalId) modelVersion := &openapi.ModelVersion{ - Name: &modelVersionName, - ExternalID: &versionExternalId, + Name: &modelVersionName, + ExternalID: &versionExternalId, + Description: &modelVersionDescription, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -136,22 +143,22 @@ func TestModelRegistryTypes(t *testing.T) { // assure the types have been correctly setup at startup ctx := context.Background() regModelResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ - TypeName: &core.RegisteredModelTypeName, + TypeName: registeredModelTypeName, }) - assertion.NotNilf(regModelResp.ContextType, "registered model type %s should exists", core.RegisteredModelTypeName) - assertion.Equal(core.RegisteredModelTypeName, *regModelResp.ContextType.Name) + assertion.NotNilf(regModelResp.ContextType, "registered model type %s should exists", *registeredModelTypeName) + assertion.Equal(*registeredModelTypeName, *regModelResp.ContextType.Name) modelVersionResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ - TypeName: &core.ModelVersionTypeName, + TypeName: modelVersionTypeName, }) - assertion.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", core.ModelVersionTypeName) - assertion.Equal(core.ModelVersionTypeName, *modelVersionResp.ContextType.Name) + assertion.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) + assertion.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) modelArtifactResp, _ := client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ - TypeName: &core.ModelArtifactTypeName, + TypeName: modelArtifactTypeName, }) - assertion.NotNilf(modelArtifactResp.ArtifactType, "model version type %s should exists", core.ModelArtifactTypeName) - assertion.Equal(core.ModelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) + assertion.NotNilf(modelArtifactResp.ArtifactType, "model version type %s should exists", *modelArtifactTypeName) + assertion.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) } // REGISTERED MODELS @@ -165,8 +172,9 @@ func TestCreateRegisteredModel(t *testing.T) { // register a new model registeredModel := &openapi.RegisteredModel{ - Name: &modelName, - ExternalID: &modelExternalId, + Name: &modelName, + ExternalID: &modelExternalId, + Description: &modelDescription, CustomProperties: &map[string]openapi.MetadataValue{ "owner": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -183,17 +191,18 @@ func TestCreateRegisteredModel(t *testing.T) { assertion.Nilf(err, "error creating registered model: %v", err) assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") - createdModelId, _ := mapper.IdToInt64(*createdModel.Id) + createdModelId, _ := converter.StringToInt64(createdModel.Id) ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{*createdModelId}, }) assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - ctxId := mapper.IdToString(*ctx.Id) + ctxId := converter.Int64ToString(ctx.Id) assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") assertion.Equal(modelExternalId, *ctx.ExternalId, "saved external id should match the provided one") + assertion.Equal(modelDescription, ctx.Properties["description"].GetStringValue(), "saved description should match the provided one") assertion.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) @@ -227,7 +236,7 @@ func TestUpdateRegisteredModel(t *testing.T) { // checks assertion.Nilf(err, "error creating registered model: %v", err) assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") - createdModelId, _ := mapper.IdToInt64(*createdModel.Id) + createdModelId, _ := converter.StringToInt64(createdModel.Id) // checks created model matches original one except for Id assertion.Equal(*registeredModel.Name, *createdModel.Name, "returned model name should match the original one") @@ -260,7 +269,7 @@ func TestUpdateRegisteredModel(t *testing.T) { assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - ctxId := mapper.IdToString(*ctx.Id) + ctxId := converter.Int64ToString(ctx.Id) assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") assertion.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") @@ -284,7 +293,7 @@ func TestUpdateRegisteredModel(t *testing.T) { assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx = ctxById.Contexts[0] - ctxId = mapper.IdToString(*ctx.Id) + ctxId = converter.Int64ToString(ctx.Id) assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") assertion.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") @@ -423,7 +432,7 @@ func TestGetRegisteredModelsOrderedById(t *testing.T) { _, err = service.UpsertRegisteredModel(registeredModel) assertion.Nilf(err, "error creating registered model: %v", err) - orderedById, err := service.GetRegisteredModels(core.ListOptions{ + orderedById, err := service.GetRegisteredModels(ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) @@ -434,7 +443,7 @@ func TestGetRegisteredModelsOrderedById(t *testing.T) { assertion.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) } - orderedById, err = service.GetRegisteredModels(core.ListOptions{ + orderedById, err = service.GetRegisteredModels(ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) @@ -483,7 +492,7 @@ func TestGetRegisteredModelsOrderedByLastUpdate(t *testing.T) { _, err = service.UpsertRegisteredModel(secondModel) assertion.Nilf(err, "error creating registered model: %v", err) - orderedById, err := service.GetRegisteredModels(core.ListOptions{ + orderedById, err := service.GetRegisteredModels(ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) @@ -494,7 +503,7 @@ func TestGetRegisteredModelsOrderedByLastUpdate(t *testing.T) { assertion.Equal(*thirdModel.Id, *orderedById.Items[1].Id) assertion.Equal(*secondModel.Id, *orderedById.Items[2].Id) - orderedById, err = service.GetRegisteredModels(core.ListOptions{ + orderedById, err = service.GetRegisteredModels(ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) @@ -541,7 +550,7 @@ func TestGetRegisteredModelsWithPageSize(t *testing.T) { thirdModel, err := service.UpsertRegisteredModel(registeredModel) assertion.Nilf(err, "error creating registered model: %v", err) - truncatedList, err := service.GetRegisteredModels(core.ListOptions{ + truncatedList, err := service.GetRegisteredModels(ListOptions{ PageSize: &pageSize, }) assertion.Nilf(err, "error getting registered models: %v", err) @@ -550,7 +559,7 @@ func TestGetRegisteredModelsWithPageSize(t *testing.T) { assertion.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") assertion.Equal(*firstModel.Id, *truncatedList.Items[0].Id) - truncatedList, err = service.GetRegisteredModels(core.ListOptions{ + truncatedList, err = service.GetRegisteredModels(ListOptions{ PageSize: &pageSize2, NextPageToken: &truncatedList.NextPageToken, }) @@ -574,8 +583,9 @@ func TestCreateModelVersion(t *testing.T) { registeredModelId := registerModel(assertion, service, nil, nil) modelVersion := &openapi.ModelVersion{ - Name: &modelVersionName, - ExternalID: &versionExternalId, + Name: &modelVersionName, + ExternalID: &versionExternalId, + Description: &modelVersionDescription, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -590,7 +600,7 @@ func TestCreateModelVersion(t *testing.T) { assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") - createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + createdVersionId, _ := converter.StringToInt64(createdVersion.Id) byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ @@ -604,7 +614,8 @@ func TestCreateModelVersion(t *testing.T) { assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") assertion.Equal(versionExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") - assertion.Equalf(core.ModelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", core.ModelVersionTypeName) + assertion.Equal(modelVersionDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") + assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) @@ -666,7 +677,7 @@ func TestUpdateModelVersion(t *testing.T) { assertion.Nilf(err, "error creating new model version for %d", registeredModelId) assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") - createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + createdVersionId, _ := converter.StringToInt64(createdVersion.Id) newExternalId := "org.my_awesome_model@v1" newScore := 0.95 @@ -681,7 +692,7 @@ func TestUpdateModelVersion(t *testing.T) { updatedVersion, err := service.UpsertModelVersion(createdVersion, ®isteredModelId) assertion.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) - updateVersionId, _ := mapper.IdToInt64(*updatedVersion.Id) + updateVersionId, _ := converter.StringToInt64(updatedVersion.Id) assertion.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ @@ -697,7 +708,7 @@ func TestUpdateModelVersion(t *testing.T) { assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") - assertion.Equalf(core.ModelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", core.ModelVersionTypeName) + assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) @@ -711,7 +722,7 @@ func TestUpdateModelVersion(t *testing.T) { updatedVersion, err = service.UpsertModelVersion(updatedVersion, ®isteredModelId) assertion.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) - updateVersionId, _ = mapper.IdToInt64(*updatedVersion.Id) + updateVersionId, _ = converter.StringToInt64(updatedVersion.Id) assertion.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") byId, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ @@ -727,7 +738,7 @@ func TestUpdateModelVersion(t *testing.T) { assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") - assertion.Equalf(core.ModelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", core.ModelVersionTypeName) + assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) } func TestUpdateModelVersionFailure(t *testing.T) { @@ -797,7 +808,7 @@ func TestGetModelVersionById(t *testing.T) { assertion.Nilf(err, "error creating new model version for %d", registeredModelId) assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") - createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + createdVersionId, _ := converter.StringToInt64(createdVersion.Id) getById, err := service.GetModelVersionById(*createdVersion.Id) assertion.Nilf(err, "error getting model version with id %d", *createdVersionId) @@ -810,7 +821,7 @@ func TestGetModelVersionById(t *testing.T) { assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*getById.Id, *mapper.IdToString(*ctx.Id), "returned model version id should match the mlmd context one") + assertion.Equal(*getById.Id, *converter.Int64ToString(ctx.Id), "returned model version id should match the mlmd context one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getById.Name), *ctx.Name, "saved model name should match the provided one") assertion.Equal(*getById.ExternalID, *modelVersion.ExternalID, "saved external id should match the provided one") assertion.Equal(*(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, author, "saved author custom property should match the provided one") @@ -841,7 +852,7 @@ func TestGetModelVersionByParamsName(t *testing.T) { assertion.Nilf(err, "error creating new model version for %d", registeredModelId) assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") - createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + createdVersionId, _ := converter.StringToInt64(createdVersion.Id) getByName, err := service.GetModelVersionByParams(&modelVersionName, ®isteredModelId, nil) assertion.Nilf(err, "error getting model version by name %d", *createdVersionId) @@ -854,7 +865,7 @@ func TestGetModelVersionByParamsName(t *testing.T) { assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*mapper.IdToString(*ctx.Id), *getByName.Id, "returned model version id should match the mlmd context one") + assertion.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned model version id should match the mlmd context one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByName.Name), *ctx.Name, "saved model name should match the provided one") assertion.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByName.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") @@ -885,7 +896,7 @@ func TestGetModelVersionByParamsExternalId(t *testing.T) { assertion.Nilf(err, "error creating new model version for %d", registeredModelId) assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") - createdVersionId, _ := mapper.IdToInt64(*createdVersion.Id) + createdVersionId, _ := converter.StringToInt64(createdVersion.Id) getByExternalId, err := service.GetModelVersionByParams(nil, nil, modelVersion.ExternalID) assertion.Nilf(err, "error getting model version by external id %d", *modelVersion.ExternalID) @@ -898,7 +909,7 @@ func TestGetModelVersionByParamsExternalId(t *testing.T) { assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*mapper.IdToString(*ctx.Id), *getByExternalId.Id, "returned model version id should match the mlmd context one") + assertion.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned model version id should match the mlmd context one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByExternalId.Name), *ctx.Name, "saved model name should match the provided one") assertion.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByExternalId.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") @@ -985,34 +996,34 @@ func TestGetModelVersions(t *testing.T) { _, err = service.UpsertModelVersion(modelVersionAnother, &anotherRegisteredModelId) assertion.Nilf(err, "error creating new model version for %d", anotherRegisteredModelId) - createdVersionId1, _ := mapper.IdToInt64(*createdVersion1.Id) - createdVersionId2, _ := mapper.IdToInt64(*createdVersion2.Id) - createdVersionId3, _ := mapper.IdToInt64(*createdVersion3.Id) + createdVersionId1, _ := converter.StringToInt64(createdVersion1.Id) + createdVersionId2, _ := converter.StringToInt64(createdVersion2.Id) + createdVersionId3, _ := converter.StringToInt64(createdVersion3.Id) - getAll, err := service.GetModelVersions(core.ListOptions{}, nil) + getAll, err := service.GetModelVersions(ListOptions{}, nil) assertion.Nilf(err, "error getting all model versions") assertion.Equal(int32(4), getAll.Size, "expected four model versions across all registered models") - getAllByRegModel, err := service.GetModelVersions(core.ListOptions{}, ®isteredModelId) + getAllByRegModel, err := service.GetModelVersions(ListOptions{}, ®isteredModelId) assertion.Nilf(err, "error getting all model versions") assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) - assertion.Equal(*mapper.IdToString(*createdVersionId1), *getAllByRegModel.Items[0].Id) - assertion.Equal(*mapper.IdToString(*createdVersionId2), *getAllByRegModel.Items[1].Id) - assertion.Equal(*mapper.IdToString(*createdVersionId3), *getAllByRegModel.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[2].Id) // order by last update time, expecting last created as first orderByLastUpdate := "LAST_UPDATE_TIME" - getAllByRegModel, err = service.GetModelVersions(core.ListOptions{ + getAllByRegModel, err = service.GetModelVersions(ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, ®isteredModelId) assertion.Nilf(err, "error getting all model versions") assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) - assertion.Equal(*mapper.IdToString(*createdVersionId1), *getAllByRegModel.Items[2].Id) - assertion.Equal(*mapper.IdToString(*createdVersionId2), *getAllByRegModel.Items[1].Id) - assertion.Equal(*mapper.IdToString(*createdVersionId3), *getAllByRegModel.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[0].Id) // update the second version newVersionExternalId := "updated.org:v2" @@ -1022,16 +1033,16 @@ func TestGetModelVersions(t *testing.T) { assertion.Equal(newVersionExternalId, *createdVersion2.ExternalID) - getAllByRegModel, err = service.GetModelVersions(core.ListOptions{ + getAllByRegModel, err = service.GetModelVersions(ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, ®isteredModelId) assertion.Nilf(err, "error getting all model versions") assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) - assertion.Equal(*mapper.IdToString(*createdVersionId1), *getAllByRegModel.Items[2].Id) - assertion.Equal(*mapper.IdToString(*createdVersionId2), *getAllByRegModel.Items[0].Id) - assertion.Equal(*mapper.IdToString(*createdVersionId3), *getAllByRegModel.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[1].Id) } // MODEL ARTIFACTS @@ -1046,9 +1057,10 @@ func TestCreateModelArtifact(t *testing.T) { modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ - Name: &artifactName, - State: (*openapi.ArtifactState)(&artifactState), - Uri: &artifactUri, + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + Description: &artifactDescription, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -1066,9 +1078,10 @@ func TestCreateModelArtifact(t *testing.T) { assertion.Equal(artifactName, *createdArtifact.Name) assertion.Equal(*state, *createdArtifact.State) assertion.Equal(artifactUri, *createdArtifact.Uri) + assertion.Equal(artifactDescription, *createdArtifact.Description) assertion.Equal(author, *(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue) - createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) + createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) getById, err := client.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ ArtifactIds: []int64{*createdArtifactId}, }) @@ -1078,9 +1091,10 @@ func TestCreateModelArtifact(t *testing.T) { assertion.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) assertion.Equal(string(*createdArtifact.State), getById.Artifacts[0].State.String()) assertion.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) + assertion.Equal(*createdArtifact.Description, getById.Artifacts[0].Properties["description"].GetStringValue()) assertion.Equal(*(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["author"].GetStringValue()) - modelVersionIdAsInt, _ := mapper.IdToInt64(modelVersionId) + modelVersionIdAsInt, _ := converter.StringToInt64(&modelVersionId) byCtx, _ := client.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ ContextId: (*int64)(modelVersionIdAsInt), }) @@ -1149,8 +1163,8 @@ func TestUpdateModelArtifact(t *testing.T) { updatedArtifact, err := service.UpsertModelArtifact(createdArtifact, &modelVersionId) assertion.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) - createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) - updatedArtifactId, _ := mapper.IdToInt64(*updatedArtifact.Id) + createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) + updatedArtifactId, _ := converter.StringToInt64(updatedArtifact.Id) assertion.Equal(createdArtifactId, updatedArtifactId) getById, err := client.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ @@ -1228,7 +1242,7 @@ func TestGetModelArtifactById(t *testing.T) { createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) - createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) + createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) getById, err := service.GetModelArtifactById(*createdArtifact.Id) assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) @@ -1269,7 +1283,7 @@ func TestGetModelArtifactByParams(t *testing.T) { createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) - createdArtifactId, _ := mapper.IdToInt64(*createdArtifact.Id) + createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) state, _ := openapi.NewArtifactStateFromValue(artifactState) @@ -1393,27 +1407,27 @@ func TestGetModelArtifacts(t *testing.T) { createdArtifact3, err := service.UpsertModelArtifact(modelArtifact3, &modelVersionId) assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) - createdArtifactId1, _ := mapper.IdToInt64(*createdArtifact1.Id) - createdArtifactId2, _ := mapper.IdToInt64(*createdArtifact2.Id) - createdArtifactId3, _ := mapper.IdToInt64(*createdArtifact3.Id) + createdArtifactId1, _ := converter.StringToInt64(createdArtifact1.Id) + createdArtifactId2, _ := converter.StringToInt64(createdArtifact2.Id) + createdArtifactId3, _ := converter.StringToInt64(createdArtifact3.Id) - getAll, err := service.GetModelArtifacts(core.ListOptions{}, nil) + getAll, err := service.GetModelArtifacts(ListOptions{}, nil) assertion.Nilf(err, "error getting all model artifacts") assertion.Equalf(int32(3), getAll.Size, "expected three model artifacts") - assertion.Equal(*mapper.IdToString(*createdArtifactId1), *getAll.Items[0].Id) - assertion.Equal(*mapper.IdToString(*createdArtifactId2), *getAll.Items[1].Id) - assertion.Equal(*mapper.IdToString(*createdArtifactId3), *getAll.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdArtifactId1), *getAll.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdArtifactId2), *getAll.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdArtifactId3), *getAll.Items[2].Id) orderByLastUpdate := "LAST_UPDATE_TIME" - getAllByModelVersion, err := service.GetModelArtifacts(core.ListOptions{ + getAllByModelVersion, err := service.GetModelArtifacts(ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &modelVersionId) assertion.Nilf(err, "error getting all model artifacts for %d", modelVersionId) assertion.Equalf(int32(3), getAllByModelVersion.Size, "expected three model artifacts for model version %d", modelVersionId) - assertion.Equal(*mapper.IdToString(*createdArtifactId1), *getAllByModelVersion.Items[2].Id) - assertion.Equal(*mapper.IdToString(*createdArtifactId2), *getAllByModelVersion.Items[1].Id) - assertion.Equal(*mapper.IdToString(*createdArtifactId3), *getAllByModelVersion.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdArtifactId1), *getAllByModelVersion.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdArtifactId2), *getAllByModelVersion.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdArtifactId3), *getAllByModelVersion.Items[0].Id) } diff --git a/internal/core/mapper.go b/internal/core/mapper.go new file mode 100644 index 00000000..faed2eb1 --- /dev/null +++ b/internal/core/mapper.go @@ -0,0 +1,111 @@ +package core + +import ( + "fmt" + + "github.com/opendatahub-io/model-registry/internal/converter" + "github.com/opendatahub-io/model-registry/internal/converter/generated" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/model/openapi" +) + +type Mapper struct { + OpenAPIConverter converter.OpenAPIToMLMDConverter + MLMDConverter converter.MLMDToOpenAPIConverter + RegisteredModelTypeId int64 + ModelVersionTypeId int64 + ModelArtifactTypeId int64 +} + +func NewMapper(registeredModelTypeId int64, modelVersionTypeId int64, modelArtifactTypeId int64) *Mapper { + return &Mapper{ + OpenAPIConverter: &generated.OpenAPIToMLMDConverterImpl{}, + MLMDConverter: &generated.MLMDToOpenAPIConverterImpl{}, + RegisteredModelTypeId: registeredModelTypeId, + ModelVersionTypeId: modelVersionTypeId, + ModelArtifactTypeId: modelArtifactTypeId, + } +} + +// Utilities for OpenAPI --> MLMD mapping, make use of generated Converters + +func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel) (*proto.Context, error) { + ctx, err := m.OpenAPIConverter.ConvertRegisteredModel(&converter.OpenAPIModelWrapper[openapi.RegisteredModel]{ + TypeId: m.RegisteredModelTypeId, + Model: registeredModel, + }) + if err != nil { + return nil, err + } + + return ctx, nil +} + +func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registeredModelId string, registeredModelName *string) (*proto.Context, error) { + ctx, err := m.OpenAPIConverter.ConvertModelVersion(&converter.OpenAPIModelWrapper[openapi.ModelVersion]{ + TypeId: m.ModelVersionTypeId, + Model: modelVersion, + ParentResourceId: ®isteredModelId, + ModelName: registeredModelName, + }) + if err != nil { + return nil, err + } + + return ctx, nil +} + +func (m *Mapper) MapFromModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *string) (*proto.Artifact, error) { + + artifact, err := m.OpenAPIConverter.ConvertModelArtifact(&converter.OpenAPIModelWrapper[openapi.ModelArtifact]{ + TypeId: m.ModelArtifactTypeId, + Model: modelArtifact, + ParentResourceId: modelVersionId, + }) + if err != nil { + return nil, err + } + + return artifact, nil +} + +func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact, modelVersionId *string) ([]*proto.Artifact, error) { + artifacts := []*proto.Artifact{} + if modelArtifacts == nil { + return artifacts, nil + } + for _, a := range *modelArtifacts { + mapped, err := m.MapFromModelArtifact(&a, modelVersionId) + if err != nil { + return nil, err + } + artifacts = append(artifacts, mapped) + } + return artifacts, nil +} + +// Utilities for MLMD --> OpenAPI mapping, make use of generated Converters + +func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredModel, error) { + if ctx.GetTypeId() != m.RegisteredModelTypeId { + return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", m.RegisteredModelTypeId, ctx.GetTypeId()) + } + + return m.MLMDConverter.ConvertRegisteredModel(ctx) +} + +func (m *Mapper) MapToModelVersion(ctx *proto.Context) (*openapi.ModelVersion, error) { + if ctx.GetTypeId() != m.ModelVersionTypeId { + return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", m.ModelVersionTypeId, ctx.GetTypeId()) + } + + return m.MLMDConverter.ConvertModelVersion(ctx) +} + +func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArtifact, error) { + if artifact.GetTypeId() != m.ModelArtifactTypeId { + return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", m.ModelArtifactTypeId, artifact.GetTypeId()) + } + + return m.MLMDConverter.ConvertModelArtifact(artifact) +} diff --git a/internal/core/mapper/mlmd_mapper.go b/internal/core/mapper/mlmd_mapper.go deleted file mode 100644 index dc45f7b1..00000000 --- a/internal/core/mapper/mlmd_mapper.go +++ /dev/null @@ -1,377 +0,0 @@ -package mapper - -import ( - "encoding/base64" - "encoding/json" - "fmt" - "strconv" - "strings" - - "github.com/google/uuid" - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" - "google.golang.org/protobuf/types/known/structpb" -) - -type Mapper struct { - RegisteredModelTypeId int64 - ModelVersionTypeId int64 - ModelArtifactTypeId int64 -} - -func NewMapper(registeredModelTypeId int64, modelVersionTypeId int64, modelArtifactTypeId int64) *Mapper { - return &Mapper{ - RegisteredModelTypeId: registeredModelTypeId, - ModelVersionTypeId: modelVersionTypeId, - ModelArtifactTypeId: modelArtifactTypeId, - } -} - -func IdToInt64(idString string) (*int64, error) { - idInt, err := strconv.Atoi(idString) - if err != nil { - return nil, err - } - - idInt64 := int64(idInt) - - return &idInt64, nil -} - -func IdToString(idInt int64) *string { - idString := strconv.FormatInt(idInt, 10) - - return &idString -} - -// Internal Model --> MLMD - -// Map generic map into MLMD [custom] properties object -func (m *Mapper) MapToProperties(data map[string]openapi.MetadataValue) (map[string]*proto.Value, error) { - props := make(map[string]*proto.Value) - - for key, v := range data { - value := proto.Value{} - - switch { - // bool value - case v.MetadataBoolValue != nil: - value.Value = &proto.Value_BoolValue{BoolValue: *v.MetadataBoolValue.BoolValue} - // int value - case v.MetadataIntValue != nil: - intValue, err := IdToInt64(*v.MetadataIntValue.IntValue) - if err != nil { - return nil, fmt.Errorf("unable to decode as int64 %w for key %s", err, key) - } - value.Value = &proto.Value_IntValue{IntValue: *intValue} - // double value - case v.MetadataDoubleValue != nil: - value.Value = &proto.Value_DoubleValue{DoubleValue: *v.MetadataDoubleValue.DoubleValue} - // string value - case v.MetadataStringValue != nil: - value.Value = &proto.Value_StringValue{StringValue: *v.MetadataStringValue.StringValue} - // struct value - case v.MetadataStructValue != nil: - data, err := base64.StdEncoding.DecodeString(*v.MetadataStructValue.StructValue) - if err != nil { - return nil, fmt.Errorf("unable to decode %w for key %s", err, key) - } - var asMap map[string]interface{} - err = json.Unmarshal(data, &asMap) - if err != nil { - return nil, fmt.Errorf("unable to decode %w for key %s", err, key) - } - asStruct, err := structpb.NewStruct(asMap) - if err != nil { - return nil, fmt.Errorf("unable to decode %w for key %s", err, key) - } - value.Value = &proto.Value_StructValue{ - StructValue: asStruct, - } - default: - return nil, fmt.Errorf("type mapping not found for %s:%v", key, v) - } - - props[key] = &value - } - - return props, nil -} - -func (m *Mapper) MapToArtifactState(oapiState *openapi.ArtifactState) *proto.Artifact_State { - if oapiState == nil { - return nil - } - - state := (proto.Artifact_State)(proto.Artifact_State_value[string(*oapiState)]) - return &state -} - -func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel) (*proto.Context, error) { - var idInt *int64 - if registeredModel.Id != nil { - var err error - idInt, err = IdToInt64(*registeredModel.Id) - if err != nil { - return nil, err - } - } - - customProps := make(map[string]*proto.Value) - if registeredModel.CustomProperties != nil { - customProps, _ = m.MapToProperties(*registeredModel.CustomProperties) - } - - return &proto.Context{ - Id: idInt, - TypeId: &m.RegisteredModelTypeId, - Name: registeredModel.Name, - ExternalId: registeredModel.ExternalID, - CustomProperties: customProps, - }, nil -} - -func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registeredModelId int64, registeredModelName *string) (*proto.Context, error) { - fullName := PrefixWhenOwned(®isteredModelId, *modelVersion.Name) - customProps := make(map[string]*proto.Value) - if modelVersion.CustomProperties != nil { - customProps, _ = m.MapToProperties(*modelVersion.CustomProperties) - } - - var idAsInt *int64 - if modelVersion.Id != nil { - var err error - idAsInt, err = IdToInt64(*modelVersion.Id) - if err != nil { - return nil, err - } - } - ctx := &proto.Context{ - Id: idAsInt, - Name: &fullName, - TypeId: &m.ModelVersionTypeId, - ExternalId: modelVersion.ExternalID, - Properties: map[string]*proto.Value{ - "model_name": { - Value: &proto.Value_StringValue{ - StringValue: *registeredModelName, - }, - }, - }, - CustomProperties: customProps, - } - if modelVersion.Name != nil { - ctx.Properties["version"] = &proto.Value{ - Value: &proto.Value_StringValue{ - StringValue: *modelVersion.Name, - }, - } - } - // TODO: missing explicit property in openapi - // if modelVersion.Author != nil { - // ctx.Properties["author"] = &proto.Value{ - // Value: &proto.Value_StringValue{ - // StringValue: *modelVersion.Author, - // }, - // } - // } - - return ctx, nil -} - -func (m *Mapper) MapFromModelArtifact(modelArtifact openapi.ModelArtifact, modelVersionId *int64) *proto.Artifact { - // openapi.Artifact is defined with optional name, so build arbitrary name for this artifact if missing - var artifactName string - if modelArtifact.Name != nil { - artifactName = *modelArtifact.Name - } else { - artifactName = uuid.New().String() - } - // build fullName for mlmd storage - fullName := PrefixWhenOwned(modelVersionId, artifactName) - - customProps := make(map[string]*proto.Value) - if modelArtifact.CustomProperties != nil { - customProps, _ = m.MapToProperties(*modelArtifact.CustomProperties) - } - - var idAsInt *int64 - if modelArtifact.Id != nil { - idAsInt, _ = IdToInt64(*modelArtifact.Id) - } - - return &proto.Artifact{ - Id: idAsInt, - TypeId: &m.ModelArtifactTypeId, - Name: &fullName, - Uri: modelArtifact.Uri, - ExternalId: modelArtifact.ExternalID, - State: m.MapToArtifactState(modelArtifact.State), - CustomProperties: customProps, - } -} - -func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact, modelVersionId *int64) ([]*proto.Artifact, error) { - artifacts := []*proto.Artifact{} - if modelArtifacts == nil { - return artifacts, nil - } - for _, a := range *modelArtifacts { - artifacts = append(artifacts, m.MapFromModelArtifact(a, modelVersionId)) - } - return artifacts, nil -} - -// MLMD --> Internal Model - -// Maps MLMD properties into a generic map -func (m *Mapper) MapFromProperties(props map[string]*proto.Value) (map[string]openapi.MetadataValue, error) { - data := make(map[string]openapi.MetadataValue) - - for key, v := range props { - // data[key] = v.Value - customValue := openapi.MetadataValue{} - - switch typedValue := v.Value.(type) { - case *proto.Value_BoolValue: - customValue.MetadataBoolValue = &openapi.MetadataBoolValue{ - BoolValue: &typedValue.BoolValue, - } - case *proto.Value_IntValue: - customValue.MetadataIntValue = &openapi.MetadataIntValue{ - IntValue: IdToString(typedValue.IntValue), - } - case *proto.Value_DoubleValue: - customValue.MetadataDoubleValue = &openapi.MetadataDoubleValue{ - DoubleValue: &typedValue.DoubleValue, - } - case *proto.Value_StringValue: - customValue.MetadataStringValue = &openapi.MetadataStringValue{ - StringValue: &typedValue.StringValue, - } - case *proto.Value_StructValue: - sv := typedValue.StructValue - asMap := sv.AsMap() - asJSON, err := json.Marshal(asMap) - if err != nil { - return nil, err - } - b64 := base64.StdEncoding.EncodeToString(asJSON) - customValue.MetadataStructValue = &openapi.MetadataStructValue{ - StructValue: &b64, - } - default: - return nil, fmt.Errorf("type mapping not found for %s:%v", key, v) - } - - data[key] = customValue - } - - return data, nil -} - -func (m *Mapper) MapFromArtifactState(mlmdState *proto.Artifact_State) *openapi.ArtifactState { - if mlmdState == nil { - return nil - } - - state := mlmdState.String() - return (*openapi.ArtifactState)(&state) -} - -func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredModel, error) { - if ctx.GetTypeId() != m.RegisteredModelTypeId { - return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.RegisteredModelTypeId, ctx.GetTypeId()) - } - - customProps, err := m.MapFromProperties(ctx.CustomProperties) - if err != nil { - return nil, err - } - - idString := strconv.FormatInt(*ctx.Id, 10) - - model := &openapi.RegisteredModel{ - Id: &idString, - Name: ctx.Name, - ExternalID: ctx.ExternalId, - CustomProperties: &customProps, - } - - return model, nil -} - -func (m *Mapper) MapToModelVersion(ctx *proto.Context) (*openapi.ModelVersion, error) { - if ctx.GetTypeId() != m.ModelVersionTypeId { - return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.ModelVersionTypeId, ctx.GetTypeId()) - } - - metadata, err := m.MapFromProperties(ctx.CustomProperties) - if err != nil { - return nil, err - } - - // modelName := ctx.GetProperties()["model_name"].GetStringValue() - // version := ctx.GetProperties()["version"].GetStringValue() - // author := ctx.GetProperties()["author"].GetStringValue() - - idString := strconv.FormatInt(*ctx.Id, 10) - - name := NameFromOwned(*ctx.Name) - modelVersion := &openapi.ModelVersion{ - // ModelName: &modelName, - Id: &idString, - Name: &name, - ExternalID: ctx.ExternalId, - // Author: &author, - CustomProperties: &metadata, - } - - return modelVersion, nil -} - -func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArtifact, error) { - if artifact.GetTypeId() != m.ModelArtifactTypeId { - return nil, fmt.Errorf("invalid TypeId, exptected %d but received %d", m.ModelArtifactTypeId, artifact.GetTypeId()) - } - - customProps, err := m.MapFromProperties(artifact.CustomProperties) - if err != nil { - return nil, err - } - - _, err = m.MapFromProperties(artifact.Properties) - if err != nil { - return nil, err - } - - name := NameFromOwned(*artifact.Name) - modelArtifact := &openapi.ModelArtifact{ - Id: IdToString(*artifact.Id), - Uri: artifact.Uri, - Name: &name, - ExternalID: artifact.ExternalId, - State: m.MapFromArtifactState(artifact.State), - CustomProperties: &customProps, - } - - return modelArtifact, nil -} - -// For owned entity such as ModelVersion -// for potentially owned entity such as ModelArtifact -// compose the mlmd fullname by using ownerId as prefix -func PrefixWhenOwned(ownerId *int64, entityName string) string { - if ownerId != nil { - return fmt.Sprintf("%d:%s", *ownerId, entityName) - } - uuidPrefix := uuid.New().String() - return fmt.Sprintf("%s:%s", uuidPrefix, entityName) -} - -// For owned entity such as ModelVersion -// for potentially owned entity such as ModelArtifact -// derive the entity name from the mlmd fullname -func NameFromOwned(fullName string) string { - return strings.Split(fullName, ":")[1] -} diff --git a/internal/core/mapper/mlmd_mapper_test.go b/internal/core/mapper/mlmd_mapper_test.go deleted file mode 100644 index d9203475..00000000 --- a/internal/core/mapper/mlmd_mapper_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package mapper_test - -import ( - "encoding/base64" - "encoding/json" - "testing" - - "github.com/opendatahub-io/model-registry/internal/core/mapper" - "github.com/opendatahub-io/model-registry/internal/model/openapi" - "github.com/stretchr/testify/assert" - "golang.org/x/exp/maps" -) - -func TestMetadataValueBool(t *testing.T) { - data := make(map[string]openapi.MetadataValue) - key := "my bool" - mdValue := true - data[key] = openapi.MetadataBoolValueAsMetadataValue(&openapi.MetadataBoolValue{BoolValue: &mdValue}) - - roundTripAndAssert(t, data, key) -} - -func TestMetadataValueInt(t *testing.T) { - data := make(map[string]openapi.MetadataValue) - key := "my int" - mdValue := "987" - data[key] = openapi.MetadataIntValueAsMetadataValue(&openapi.MetadataIntValue{IntValue: &mdValue}) - - roundTripAndAssert(t, data, key) -} - -func TestMetadataValueIntFailure(t *testing.T) { - data := make(map[string]openapi.MetadataValue) - key := "my int" - mdValue := "not a number" - data[key] = openapi.MetadataIntValueAsMetadataValue(&openapi.MetadataIntValue{IntValue: &mdValue}) - - mapper, assert := setup(t) - asGRPC, err := mapper.MapToProperties(data) - if err == nil { - assert.Fail("Did not expected a converted value but an error: %v", asGRPC) - } -} - -func TestMetadataValueDouble(t *testing.T) { - data := make(map[string]openapi.MetadataValue) - key := "my double" - mdValue := 3.1415 - data[key] = openapi.MetadataDoubleValueAsMetadataValue(&openapi.MetadataDoubleValue{DoubleValue: &mdValue}) - - roundTripAndAssert(t, data, key) -} - -func TestMetadataValueString(t *testing.T) { - data := make(map[string]openapi.MetadataValue) - key := "my string" - mdValue := "Hello, World!" - data[key] = openapi.MetadataStringValueAsMetadataValue(&openapi.MetadataStringValue{StringValue: &mdValue}) - - roundTripAndAssert(t, data, key) -} - -func TestMetadataValueStruct(t *testing.T) { - data := make(map[string]openapi.MetadataValue) - key := "my struct" - - myMap := make(map[string]interface{}) - myMap["name"] = "John Doe" - myMap["age"] = 47 - asJSON, err := json.Marshal(myMap) - if err != nil { - t.Error(err) - } - b64 := base64.StdEncoding.EncodeToString(asJSON) - data[key] = openapi.MetadataStructValueAsMetadataValue(&openapi.MetadataStructValue{StructValue: &b64}) - - roundTripAndAssert(t, data, key) -} - -func TestMetadataValueProtoUnsupported(t *testing.T) { - data := make(map[string]openapi.MetadataValue) - key := "my proto" - - myMap := make(map[string]interface{}) - myMap["name"] = "John Doe" - myMap["age"] = 47 - asJSON, err := json.Marshal(myMap) - if err != nil { - t.Error(err) - } - b64 := base64.StdEncoding.EncodeToString(asJSON) - typeDef := "map[string]openapi.MetadataValue" - data[key] = openapi.MetadataProtoValueAsMetadataValue(&openapi.MetadataProtoValue{ - Type: &typeDef, - ProtoValue: &b64, - }) - - mapper, assert := setup(t) - asGRPC, err := mapper.MapToProperties(data) - if err == nil { - assert.Fail("Did not expected a converted value but an error: %v", asGRPC) - } -} - -func roundTripAndAssert(t *testing.T, data map[string]openapi.MetadataValue, key string) { - mapper, assert := setup(t) - - // first half - asGRPC, err := mapper.MapToProperties(data) - if err != nil { - t.Error(err) - } - assert.Contains(maps.Keys(asGRPC), key) - - // second half - unmarshall, err := mapper.MapFromProperties(asGRPC) - if err != nil { - t.Error(err) - } - assert.Equal(data, unmarshall, "result of round-trip shall be equal to original data") -} - -func setup(t *testing.T) (*mapper.Mapper, *assert.Assertions) { - return mapper.NewMapper(1, 2, 3), assert.New(t) -} From 268cc310d41887da297eeff5f3dc5487194d2261 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 07:17:48 +0000 Subject: [PATCH 098/254] Bump github.com/spf13/cobra from 1.7.0 to 1.8.0 (#126) --- go.mod | 4 ++-- go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 6b3fce08..8366403a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 github.com/searKing/golang/tools/go-enum v1.2.97 github.com/soheilhy/cmux v0.1.5 - github.com/spf13/cobra v1.7.0 + github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.17.0 github.com/stretchr/testify v1.8.4 @@ -51,7 +51,7 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/containerd/containerd v1.7.7 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/cucumber/godog v0.13.0 github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.7+incompatible // indirect diff --git a/go.sum b/go.sum index bd5c215b..5ab01138 100644 --- a/go.sum +++ b/go.sum @@ -75,8 +75,9 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= @@ -305,8 +306,9 @@ github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= From 20cb2315b37be28a0deb04b4890a2f385eb503d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Nov 2023 07:20:59 +0000 Subject: [PATCH 099/254] Bump golang.org/x/sync from 0.4.0 to 0.5.0 (#127) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 8366403a..e7ade3ca 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 github.com/vektah/gqlparser/v2 v2.5.10 - golang.org/x/sync v0.4.0 + golang.org/x/sync v0.5.0 google.golang.org/grpc v1.59.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 diff --git a/go.sum b/go.sum index 5ab01138..9e62db56 100644 --- a/go.sum +++ b/go.sum @@ -459,8 +459,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= +golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From c0d00e57335e0f11504a5903e64b54896ca213de Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Tue, 7 Nov 2023 10:55:48 +0100 Subject: [PATCH 100/254] Implement REST API Server for Model Registry (#108) * WIP working manually * Increase REST wirings and cover with Robot * Align to a309537 Improve core layer testing #85 * Implement opeanpi models converter * Treat coreApi as interface * Align to ModelArtifact comment, not resolved yet * Automate type_asserts generation with gen/openapi-server * Add Robot for Data Layer mapping implementing REST(Go)<->gRPC * Add check for artifactType * Wire REST FindXXX to core GetXXXByParams * Wire REST GetXXXYYY to core API methods * Wire REST UpdateXXX to core UpsertXXX methods * Use localhost for Robot file * Align to goverter changes * rebase goverter implementation * Update cmd/proxy.go Co-authored-by: Andrea Lamparelli --------- Co-authored-by: Andrea Lamparelli --- .gitignore | 6 + .openapi-generator-ignore | 2 +- Makefile | 6 +- api/openapi/model-registry.yaml | 8 + cmd/proxy.go | 52 +- go.mod | 1 + go.sum | 2 + .../generated/openapi_converter.gen.go | 396 +++++++++++++ internal/converter/opeanpi_converter.go | 28 + .../converter/openapi_mlmd_converter_util.go | 11 + internal/model/openapi/configuration.go | 4 + .../model/openapi/model_model_artifact.go | 2 + internal/server/openapi/api.go | 5 +- .../openapi/api_model_registry_service.go | 9 +- .../api_model_registry_service_service.go | 551 ++++++++---------- internal/server/openapi/routers.go | 16 +- internal/server/openapi/type_asserts.go | 91 ++- patches/type_asserts.patch | 29 + scripts/gen_type_asserts.sh | 53 ++ templates/go-server/model.mustache | 112 ++++ test/robot/MLMetadata.py | 10 + test/robot/MRandLogicalModel.robot | 56 ++ test/robot/MRviaPython.resource | 17 + test/robot/MRviaREST.resource | 52 ++ test/robot/UserStory.robot | 20 + 25 files changed, 1196 insertions(+), 343 deletions(-) create mode 100755 internal/converter/generated/openapi_converter.gen.go create mode 100644 internal/converter/opeanpi_converter.go create mode 100644 patches/type_asserts.patch create mode 100755 scripts/gen_type_asserts.sh create mode 100644 templates/go-server/model.mustache create mode 100644 test/robot/MLMetadata.py create mode 100644 test/robot/MRandLogicalModel.robot create mode 100644 test/robot/MRviaPython.resource create mode 100644 test/robot/MRviaREST.resource create mode 100644 test/robot/UserStory.robot diff --git a/.gitignore b/.gitignore index e9ecdf6b..391945a9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,9 @@ model-registry metadata.sqlite.db vendor + +# Robot Framework files +log.html +output.xml +report.html +__pycache__ diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index 40209379..254e4377 100644 --- a/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -42,6 +42,6 @@ internal/model/openapi/go.sum internal/server/openapi/api internal/server/openapi/api/** internal/server/openapi/.openapi-generator-ignore +internal/server/openapi/api_model_registry_service_service.go internal/server/openapi/README.md internal/server/openapi/main.go -internal/server/openapi/model_*.go diff --git a/Makefile b/Makefile index 0d677336..5730733d 100644 --- a/Makefile +++ b/Makefile @@ -80,8 +80,10 @@ openapi/validate: bin/openapi-generator-cli .PHONY: gen/openapi-server gen/openapi-server: bin/openapi-generator-cli openapi/validate openapi-generator-cli generate \ - -i api/openapi/model-registry.yaml -g go-server -o internal/server/openapi --package-name openapi \ - --ignore-file-override ./.openapi-generator-ignore --additional-properties=outputAsLibrary=true,enumClassPrefix=true,router=chi,sourceFolder=,onlyInterfaces=true + -i api/openapi/model-registry.yaml -g go-server -o internal/server/openapi --package-name openapi --global-property models \ + --ignore-file-override ./.openapi-generator-ignore --additional-properties=outputAsLibrary=true,enumClassPrefix=true,router=chi,sourceFolder=,onlyInterfaces=true,isGoSubmodule=true,enumClassPrefix=true,useOneOfDiscriminatorLookup=true \ + --template-dir ./templates/go-server + ./scripts/gen_type_asserts.sh gofmt -w internal/server/openapi # generate the openapi schema model and client diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index b4991d2f..511b237b 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -9,6 +9,8 @@ info: servers: - url: 'https://localhost:8080' + - + url: 'http://localhost:8080' paths: /api/model_registry/v1alpha1/model_artifact: summary: Path used to search for a modelartifact. @@ -1044,6 +1046,12 @@ components: $ref: '#/components/schemas/BaseArtifact' - $ref: '#/components/schemas/ModelArtifactCreate' + - + type: object + properties: + artifactType: + type: string + default: "model-artifact" RegisteredModel: description: A registered model in model registry. A registered model has ModelVersion children. allOf: diff --git a/cmd/proxy.go b/cmd/proxy.go index 167ded09..75bb88c7 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -1,12 +1,17 @@ package cmd import ( + "context" "fmt" + "log" + "net/http" + "github.com/golang/glog" + "github.com/opendatahub-io/model-registry/internal/core" "github.com/opendatahub-io/model-registry/internal/server/openapi" "github.com/spf13/cobra" - "log" - "net/http" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" ) var ( @@ -25,7 +30,27 @@ hostname and port where it listens.'`, func runProxyServer(cmd *cobra.Command, args []string) error { glog.Infof("proxy server started at %s:%v", cfg.Hostname, cfg.Port) - ModelRegistryServiceAPIService := openapi.NewModelRegistryServiceAPIService() + mlmdAddr := fmt.Sprintf("%s:%d", proxyCfg.MLMDHostname, proxyCfg.MLMDPort) + glog.Infof("MLMD server %s", mlmdAddr) + conn, err := grpc.DialContext( + context.Background(), + mlmdAddr, + grpc.WithReturnConnectionError(), + grpc.WithBlock(), + grpc.WithTransportCredentials(insecure.NewCredentials()), + ) + if err != nil { + log.Fatalf("Error dialing connection to mlmd server %s: %v", mlmdAddr, err) + return err + } + defer conn.Close() + service, err := core.NewModelRegistryService(conn) + if err != nil { + log.Fatalf("Error creating core service: %v", err) + return err + } + + ModelRegistryServiceAPIService := openapi.NewModelRegistryServiceAPIService(service) ModelRegistryServiceAPIController := openapi.NewModelRegistryServiceAPIController(ModelRegistryServiceAPIService) router := openapi.NewRouter(ModelRegistryServiceAPIController) @@ -37,14 +62,19 @@ func runProxyServer(cmd *cobra.Command, args []string) error { func init() { rootCmd.AddCommand(proxyCmd) - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // proxyCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: proxyCmd.Flags().StringVarP(&cfg.Hostname, "hostname", "n", cfg.Hostname, "Proxy server listen hostname") proxyCmd.Flags().IntVarP(&cfg.Port, "port", "p", cfg.Port, "Proxy server listen port") + + proxyCmd.Flags().StringVar(&proxyCfg.MLMDHostname, "mlmdhostname", proxyCfg.MLMDHostname, "MLMD hostname") + proxyCmd.Flags().IntVar(&proxyCfg.MLMDPort, "mlmdport", proxyCfg.MLMDPort, "MLMD port") +} + +type ProxyConfig struct { + MLMDHostname string + MLMDPort int +} + +var proxyCfg = ProxyConfig{ + MLMDHostname: "localhost", + MLMDPort: 8081, } diff --git a/go.mod b/go.mod index e7ade3ca..6368e09d 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.19 require ( github.com/99designs/gqlgen v0.17.40 github.com/go-chi/chi/v5 v5.0.10 + github.com/go-chi/cors v1.2.1 github.com/golang/glog v1.1.2 github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 github.com/searKing/golang/tools/go-enum v1.2.97 diff --git a/go.sum b/go.sum index 9e62db56..35f9c9d4 100644 --- a/go.sum +++ b/go.sum @@ -114,6 +114,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= +github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go new file mode 100755 index 00000000..ea22c3c0 --- /dev/null +++ b/internal/converter/generated/openapi_converter.gen.go @@ -0,0 +1,396 @@ +// Code generated by github.com/jmattheis/goverter, DO NOT EDIT. + +package generated + +import openapi "github.com/opendatahub-io/model-registry/internal/model/openapi" + +type OpenAPIConverterImpl struct{} + +func (c *OpenAPIConverterImpl) ConvertModelArtifactCreate(source *openapi.ModelArtifactCreate) (*openapi.ModelArtifact, error) { + var pOpenapiModelArtifact *openapi.ModelArtifact + if source != nil { + var openapiModelArtifact openapi.ModelArtifact + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiModelArtifact.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiModelArtifact.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiModelArtifact.ExternalID = pString2 + var pString3 *string + if (*source).Uri != nil { + xstring3 := *(*source).Uri + pString3 = &xstring3 + } + openapiModelArtifact.Uri = pString3 + var pOpenapiArtifactState *openapi.ArtifactState + if (*source).State != nil { + openapiArtifactState := openapi.ArtifactState(*(*source).State) + pOpenapiArtifactState = &openapiArtifactState + } + openapiModelArtifact.State = pOpenapiArtifactState + var pString4 *string + if (*source).Name != nil { + xstring4 := *(*source).Name + pString4 = &xstring4 + } + openapiModelArtifact.Name = pString4 + var pString5 *string + if (*source).ModelFormatName != nil { + xstring5 := *(*source).ModelFormatName + pString5 = &xstring5 + } + openapiModelArtifact.ModelFormatName = pString5 + var pString6 *string + if (*source).Runtime != nil { + xstring6 := *(*source).Runtime + pString6 = &xstring6 + } + openapiModelArtifact.Runtime = pString6 + var pString7 *string + if (*source).StorageKey != nil { + xstring7 := *(*source).StorageKey + pString7 = &xstring7 + } + openapiModelArtifact.StorageKey = pString7 + var pString8 *string + if (*source).StoragePath != nil { + xstring8 := *(*source).StoragePath + pString8 = &xstring8 + } + openapiModelArtifact.StoragePath = pString8 + var pString9 *string + if (*source).ModelFormatVersion != nil { + xstring9 := *(*source).ModelFormatVersion + pString9 = &xstring9 + } + openapiModelArtifact.ModelFormatVersion = pString9 + var pString10 *string + if (*source).ServiceAccountName != nil { + xstring10 := *(*source).ServiceAccountName + pString10 = &xstring10 + } + openapiModelArtifact.ServiceAccountName = pString10 + pOpenapiModelArtifact = &openapiModelArtifact + } + return pOpenapiModelArtifact, nil +} +func (c *OpenAPIConverterImpl) ConvertModelArtifactUpdate(source *openapi.ModelArtifactUpdate) (*openapi.ModelArtifact, error) { + var pOpenapiModelArtifact *openapi.ModelArtifact + if source != nil { + var openapiModelArtifact openapi.ModelArtifact + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiModelArtifact.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiModelArtifact.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiModelArtifact.ExternalID = pString2 + var pString3 *string + if (*source).Uri != nil { + xstring3 := *(*source).Uri + pString3 = &xstring3 + } + openapiModelArtifact.Uri = pString3 + var pOpenapiArtifactState *openapi.ArtifactState + if (*source).State != nil { + openapiArtifactState := openapi.ArtifactState(*(*source).State) + pOpenapiArtifactState = &openapiArtifactState + } + openapiModelArtifact.State = pOpenapiArtifactState + var pString4 *string + if (*source).ModelFormatName != nil { + xstring4 := *(*source).ModelFormatName + pString4 = &xstring4 + } + openapiModelArtifact.ModelFormatName = pString4 + var pString5 *string + if (*source).Runtime != nil { + xstring5 := *(*source).Runtime + pString5 = &xstring5 + } + openapiModelArtifact.Runtime = pString5 + var pString6 *string + if (*source).StorageKey != nil { + xstring6 := *(*source).StorageKey + pString6 = &xstring6 + } + openapiModelArtifact.StorageKey = pString6 + var pString7 *string + if (*source).StoragePath != nil { + xstring7 := *(*source).StoragePath + pString7 = &xstring7 + } + openapiModelArtifact.StoragePath = pString7 + var pString8 *string + if (*source).ModelFormatVersion != nil { + xstring8 := *(*source).ModelFormatVersion + pString8 = &xstring8 + } + openapiModelArtifact.ModelFormatVersion = pString8 + var pString9 *string + if (*source).ServiceAccountName != nil { + xstring9 := *(*source).ServiceAccountName + pString9 = &xstring9 + } + openapiModelArtifact.ServiceAccountName = pString9 + pOpenapiModelArtifact = &openapiModelArtifact + } + return pOpenapiModelArtifact, nil +} +func (c *OpenAPIConverterImpl) ConvertModelVersionCreate(source *openapi.ModelVersionCreate) (*openapi.ModelVersion, error) { + var pOpenapiModelVersion *openapi.ModelVersion + if source != nil { + var openapiModelVersion openapi.ModelVersion + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiModelVersion.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiModelVersion.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiModelVersion.ExternalID = pString2 + var pString3 *string + if (*source).Name != nil { + xstring3 := *(*source).Name + pString3 = &xstring3 + } + openapiModelVersion.Name = pString3 + pOpenapiModelVersion = &openapiModelVersion + } + return pOpenapiModelVersion, nil +} +func (c *OpenAPIConverterImpl) ConvertModelVersionUpdate(source *openapi.ModelVersionUpdate) (*openapi.ModelVersion, error) { + var pOpenapiModelVersion *openapi.ModelVersion + if source != nil { + var openapiModelVersion openapi.ModelVersion + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiModelVersion.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiModelVersion.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiModelVersion.ExternalID = pString2 + pOpenapiModelVersion = &openapiModelVersion + } + return pOpenapiModelVersion, nil +} +func (c *OpenAPIConverterImpl) ConvertRegisteredModelCreate(source *openapi.RegisteredModelCreate) (*openapi.RegisteredModel, error) { + var pOpenapiRegisteredModel *openapi.RegisteredModel + if source != nil { + var openapiRegisteredModel openapi.RegisteredModel + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiRegisteredModel.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiRegisteredModel.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiRegisteredModel.ExternalID = pString2 + var pString3 *string + if (*source).Name != nil { + xstring3 := *(*source).Name + pString3 = &xstring3 + } + openapiRegisteredModel.Name = pString3 + pOpenapiRegisteredModel = &openapiRegisteredModel + } + return pOpenapiRegisteredModel, nil +} +func (c *OpenAPIConverterImpl) ConvertRegisteredModelUpdate(source *openapi.RegisteredModelUpdate) (*openapi.RegisteredModel, error) { + var pOpenapiRegisteredModel *openapi.RegisteredModel + if source != nil { + var openapiRegisteredModel openapi.RegisteredModel + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiRegisteredModel.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiRegisteredModel.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiRegisteredModel.ExternalID = pString2 + pOpenapiRegisteredModel = &openapiRegisteredModel + } + return pOpenapiRegisteredModel, nil +} +func (c *OpenAPIConverterImpl) openapiMetadataValueToOpenapiMetadataValue(source openapi.MetadataValue) openapi.MetadataValue { + var openapiMetadataValue openapi.MetadataValue + openapiMetadataValue.MetadataBoolValue = c.pOpenapiMetadataBoolValueToPOpenapiMetadataBoolValue(source.MetadataBoolValue) + openapiMetadataValue.MetadataDoubleValue = c.pOpenapiMetadataDoubleValueToPOpenapiMetadataDoubleValue(source.MetadataDoubleValue) + openapiMetadataValue.MetadataIntValue = c.pOpenapiMetadataIntValueToPOpenapiMetadataIntValue(source.MetadataIntValue) + openapiMetadataValue.MetadataProtoValue = c.pOpenapiMetadataProtoValueToPOpenapiMetadataProtoValue(source.MetadataProtoValue) + openapiMetadataValue.MetadataStringValue = c.pOpenapiMetadataStringValueToPOpenapiMetadataStringValue(source.MetadataStringValue) + openapiMetadataValue.MetadataStructValue = c.pOpenapiMetadataStructValueToPOpenapiMetadataStructValue(source.MetadataStructValue) + return openapiMetadataValue +} +func (c *OpenAPIConverterImpl) pOpenapiMetadataBoolValueToPOpenapiMetadataBoolValue(source *openapi.MetadataBoolValue) *openapi.MetadataBoolValue { + var pOpenapiMetadataBoolValue *openapi.MetadataBoolValue + if source != nil { + var openapiMetadataBoolValue openapi.MetadataBoolValue + var pBool *bool + if (*source).BoolValue != nil { + xbool := *(*source).BoolValue + pBool = &xbool + } + openapiMetadataBoolValue.BoolValue = pBool + pOpenapiMetadataBoolValue = &openapiMetadataBoolValue + } + return pOpenapiMetadataBoolValue +} +func (c *OpenAPIConverterImpl) pOpenapiMetadataDoubleValueToPOpenapiMetadataDoubleValue(source *openapi.MetadataDoubleValue) *openapi.MetadataDoubleValue { + var pOpenapiMetadataDoubleValue *openapi.MetadataDoubleValue + if source != nil { + var openapiMetadataDoubleValue openapi.MetadataDoubleValue + var pFloat64 *float64 + if (*source).DoubleValue != nil { + xfloat64 := *(*source).DoubleValue + pFloat64 = &xfloat64 + } + openapiMetadataDoubleValue.DoubleValue = pFloat64 + pOpenapiMetadataDoubleValue = &openapiMetadataDoubleValue + } + return pOpenapiMetadataDoubleValue +} +func (c *OpenAPIConverterImpl) pOpenapiMetadataIntValueToPOpenapiMetadataIntValue(source *openapi.MetadataIntValue) *openapi.MetadataIntValue { + var pOpenapiMetadataIntValue *openapi.MetadataIntValue + if source != nil { + var openapiMetadataIntValue openapi.MetadataIntValue + var pString *string + if (*source).IntValue != nil { + xstring := *(*source).IntValue + pString = &xstring + } + openapiMetadataIntValue.IntValue = pString + pOpenapiMetadataIntValue = &openapiMetadataIntValue + } + return pOpenapiMetadataIntValue +} +func (c *OpenAPIConverterImpl) pOpenapiMetadataProtoValueToPOpenapiMetadataProtoValue(source *openapi.MetadataProtoValue) *openapi.MetadataProtoValue { + var pOpenapiMetadataProtoValue *openapi.MetadataProtoValue + if source != nil { + var openapiMetadataProtoValue openapi.MetadataProtoValue + var pString *string + if (*source).Type != nil { + xstring := *(*source).Type + pString = &xstring + } + openapiMetadataProtoValue.Type = pString + var pString2 *string + if (*source).ProtoValue != nil { + xstring2 := *(*source).ProtoValue + pString2 = &xstring2 + } + openapiMetadataProtoValue.ProtoValue = pString2 + pOpenapiMetadataProtoValue = &openapiMetadataProtoValue + } + return pOpenapiMetadataProtoValue +} +func (c *OpenAPIConverterImpl) pOpenapiMetadataStringValueToPOpenapiMetadataStringValue(source *openapi.MetadataStringValue) *openapi.MetadataStringValue { + var pOpenapiMetadataStringValue *openapi.MetadataStringValue + if source != nil { + var openapiMetadataStringValue openapi.MetadataStringValue + var pString *string + if (*source).StringValue != nil { + xstring := *(*source).StringValue + pString = &xstring + } + openapiMetadataStringValue.StringValue = pString + pOpenapiMetadataStringValue = &openapiMetadataStringValue + } + return pOpenapiMetadataStringValue +} +func (c *OpenAPIConverterImpl) pOpenapiMetadataStructValueToPOpenapiMetadataStructValue(source *openapi.MetadataStructValue) *openapi.MetadataStructValue { + var pOpenapiMetadataStructValue *openapi.MetadataStructValue + if source != nil { + var openapiMetadataStructValue openapi.MetadataStructValue + var pString *string + if (*source).StructValue != nil { + xstring := *(*source).StructValue + pString = &xstring + } + openapiMetadataStructValue.StructValue = pString + pOpenapiMetadataStructValue = &openapiMetadataStructValue + } + return pOpenapiMetadataStructValue +} diff --git a/internal/converter/opeanpi_converter.go b/internal/converter/opeanpi_converter.go new file mode 100644 index 00000000..7930f957 --- /dev/null +++ b/internal/converter/opeanpi_converter.go @@ -0,0 +1,28 @@ +package converter + +import "github.com/opendatahub-io/model-registry/internal/model/openapi" + +// goverter:converter +// goverter:output:file ./generated/openapi_converter.gen.go +// goverter:wrapErrors +// goverter:matchIgnoreCase +// goverter:useZeroValueOnPointerInconsistency +type OpenAPIConverter interface { + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertRegisteredModelCreate(source *openapi.RegisteredModelCreate) (*openapi.RegisteredModel, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Name + ConvertRegisteredModelUpdate(source *openapi.RegisteredModelUpdate) (*openapi.RegisteredModel, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertModelVersionCreate(source *openapi.ModelVersionCreate) (*openapi.ModelVersion, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Name + ConvertModelVersionUpdate(source *openapi.ModelVersionUpdate) (*openapi.ModelVersion, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch ArtifactType + ConvertModelArtifactCreate(source *openapi.ModelArtifactCreate) (*openapi.ModelArtifact, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch ArtifactType Name + ConvertModelArtifactUpdate(source *openapi.ModelArtifactUpdate) (*openapi.ModelArtifact, error) +} diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index a2348d49..81377019 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -37,6 +37,17 @@ func Int64ToString(id *int64) *string { return &idAsString } +// StringToInt32 converts string-based numeric value (a OpenAPI string literal consisting only of digits) to int32 if numeric, otherwise return error +func StringToInt32(idString string) (int32, error) { + idInt, err := strconv.Atoi(idString) + if err != nil { + return 0, err + } + + idInt32 := int32(idInt) + return idInt32, nil +} + // MapOpenAPICustomProperties maps OpenAPI custom properties model to MLMD one func MapOpenAPICustomProperties(source *map[string]openapi.MetadataValue) (map[string]*proto.Value, error) { props := make(map[string]*proto.Value) diff --git a/internal/model/openapi/configuration.go b/internal/model/openapi/configuration.go index 28faea4a..66a6313c 100644 --- a/internal/model/openapi/configuration.go +++ b/internal/model/openapi/configuration.go @@ -96,6 +96,10 @@ func NewConfiguration() *Configuration { URL: "https://localhost:8080", Description: "No description provided", }, + { + URL: "http://localhost:8080", + Description: "No description provided", + }, }, OperationServers: map[string]ServerConfigurations{}, } diff --git a/internal/model/openapi/model_model_artifact.go b/internal/model/openapi/model_model_artifact.go index e4ed3650..640397ee 100644 --- a/internal/model/openapi/model_model_artifact.go +++ b/internal/model/openapi/model_model_artifact.go @@ -70,6 +70,8 @@ func NewModelArtifactWithDefaults() *ModelArtifact { this := ModelArtifact{} var state ArtifactState = ARTIFACTSTATE_UNKNOWN this.State = &state + var artifactType string = "model-artifact" + this.ArtifactType = artifactType return &this } diff --git a/internal/server/openapi/api.go b/internal/server/openapi/api.go index 899f3cc7..e7c8d241 100644 --- a/internal/server/openapi/api.go +++ b/internal/server/openapi/api.go @@ -11,8 +11,9 @@ package openapi import ( "context" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" "net/http" + + model "github.com/opendatahub-io/model-registry/internal/model/openapi" ) // ModelRegistryServiceAPIRouter defines the required methods for binding the api requests to a responses for the ModelRegistryServiceAPI @@ -71,7 +72,7 @@ type ModelRegistryServiceAPIServicer interface { CreateRegisteredModelVersion(context.Context, string, model.ModelVersion) (ImplResponse, error) CreateServingEnvironment(context.Context, model.ServingEnvironmentCreate) (ImplResponse, error) FindInferenceService(context.Context, string, string) (ImplResponse, error) - FindModelArtifact(context.Context, string, string) (ImplResponse, error) + FindModelArtifact(context.Context, string, string, string) (ImplResponse, error) FindModelVersion(context.Context, string, string, string) (ImplResponse, error) FindRegisteredModel(context.Context, string, string) (ImplResponse, error) FindServingEnvironment(context.Context, string, string) (ImplResponse, error) diff --git a/internal/server/openapi/api_model_registry_service.go b/internal/server/openapi/api_model_registry_service.go index 4454a487..29c94029 100644 --- a/internal/server/openapi/api_model_registry_service.go +++ b/internal/server/openapi/api_model_registry_service.go @@ -11,11 +11,11 @@ package openapi import ( "encoding/json" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" "net/http" "strings" "github.com/go-chi/chi/v5" + model "github.com/opendatahub-io/model-registry/internal/model/openapi" ) // ModelRegistryServiceAPIController binds http requests to an api service and writes the service results to the http response @@ -496,7 +496,8 @@ func (c *ModelRegistryServiceAPIController) FindModelArtifact(w http.ResponseWri query := r.URL.Query() nameParam := query.Get("name") externalIDParam := query.Get("externalID") - result, err := c.service.FindModelArtifact(r.Context(), nameParam, externalIDParam) + parentResourceIDParam := query.Get("parentResourceID") + result, err := c.service.FindModelArtifact(r.Context(), nameParam, externalIDParam, parentResourceIDParam) // If an error occurred, encode the error with the status code if err != nil { c.errorHandler(w, r, err, &result) @@ -511,8 +512,8 @@ func (c *ModelRegistryServiceAPIController) FindModelVersion(w http.ResponseWrit query := r.URL.Query() nameParam := query.Get("name") externalIDParam := query.Get("externalID") - registeredModelIDParam := query.Get("registeredModelID") - result, err := c.service.FindModelVersion(r.Context(), nameParam, externalIDParam, registeredModelIDParam) + parentResourceIDParam := query.Get("parentResourceID") + result, err := c.service.FindModelVersion(r.Context(), nameParam, externalIDParam, parentResourceIDParam) // If an error occurred, encode the error with the status code if err != nil { c.errorHandler(w, r, err, &result) diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index bd8c4906..78cad7c1 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -12,19 +12,28 @@ package openapi import ( "context" "errors" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" "net/http" + + "github.com/opendatahub-io/model-registry/internal/converter" + "github.com/opendatahub-io/model-registry/internal/converter/generated" + "github.com/opendatahub-io/model-registry/internal/core" + model "github.com/opendatahub-io/model-registry/internal/model/openapi" ) // ModelRegistryServiceAPIService is a service that implements the logic for the ModelRegistryServiceAPIServicer -// This service should implement the business logic for every endpoint for the ModelRegistryServiceAPI API. +// This service should implement the business logic for every endpoint for the ModelRegistryServiceAPI s.coreApi. // Include any external packages or services that will be required by this service. type ModelRegistryServiceAPIService struct { + coreApi core.ModelRegistryApi + converter converter.OpenAPIConverter } // NewModelRegistryServiceAPIService creates a default api service -func NewModelRegistryServiceAPIService() ModelRegistryServiceAPIServicer { - return &ModelRegistryServiceAPIService{} +func NewModelRegistryServiceAPIService(coreApi core.ModelRegistryApi) ModelRegistryServiceAPIServicer { + return &ModelRegistryServiceAPIService{ + coreApi: coreApi, + converter: &generated.OpenAPIConverterImpl{}, + } } // CreateEnvironmentInferenceService - Create a InferenceService in ServingEnvironment @@ -115,91 +124,65 @@ func (s *ModelRegistryServiceAPIService) CreateModelArtifact(ctx context.Context // CreateModelVersion - Create a ModelVersion func (s *ModelRegistryServiceAPIService) CreateModelVersion(ctx context.Context, modelVersionCreate model.ModelVersionCreate) (ImplResponse, error) { - // TODO - update CreateModelVersion with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(201, ModelVersion{}) or use other options such as http.Ok ... - // return Response(201, ModelVersion{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil + modelVersion, err := s.converter.ConvertModelVersionCreate(&modelVersionCreate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("CreateModelVersion method not implemented") + result, err := s.coreApi.UpsertModelVersion(modelVersion, &modelVersionCreate.RegisteredModelID) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(201, result), nil + // TODO: return Response(400, Error{}), nil + // TODO: return Response(401, Error{}), nil } // CreateModelVersionArtifact - Create an Artifact in a ModelVersion func (s *ModelRegistryServiceAPIService) CreateModelVersionArtifact(ctx context.Context, modelversionId string, artifact model.Artifact) (ImplResponse, error) { - // TODO - update CreateModelVersionArtifact with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, Artifact{}) or use other options such as http.Ok ... - // return Response(200, Artifact{}), nil - - // TODO: Uncomment the next line to return response Response(201, Artifact{}) or use other options such as http.Ok ... - // return Response(201, Artifact{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("CreateModelVersionArtifact method not implemented") + if artifact.ModelArtifact == nil { + return Response(http.StatusNotImplemented, nil), errors.New("unsupported artifactType") + } + result, err := s.coreApi.UpsertModelArtifact(artifact.ModelArtifact, &modelversionId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + artifactResult := model.Artifact{ + ModelArtifact: result, + } + return Response(201, artifactResult), nil + // TODO return Response(200, Artifact{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // CreateRegisteredModel - Create a RegisteredModel func (s *ModelRegistryServiceAPIService) CreateRegisteredModel(ctx context.Context, registeredModelCreate model.RegisteredModelCreate) (ImplResponse, error) { - // TODO - update CreateRegisteredModel with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - // TODO: Uncomment the next line to return response Response(201, RegisteredModel{}) or use other options such as http.Ok ... - // return Response(201, RegisteredModel{}), nil + registeredModel, err := s.converter.ConvertRegisteredModelCreate(®isteredModelCreate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("CreateRegisteredModel method not implemented") + result, err := s.coreApi.UpsertRegisteredModel(registeredModel) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(201, result), nil + // TODO: return Response(400, Error{}), nil + // TODO: return Response(401, Error{}), nil } // CreateRegisteredModelVersion - Create a ModelVersion in RegisteredModel func (s *ModelRegistryServiceAPIService) CreateRegisteredModelVersion(ctx context.Context, registeredmodelId string, modelVersion model.ModelVersion) (ImplResponse, error) { - // TODO - update CreateRegisteredModelVersion with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(201, ModelVersion{}) or use other options such as http.Ok ... - // return Response(201, ModelVersion{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("CreateRegisteredModelVersion method not implemented") + result, err := s.coreApi.UpsertModelVersion(&modelVersion, ®isteredmodelId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(201, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // CreateServingEnvironment - Create a ServingEnvironment @@ -246,69 +229,39 @@ func (s *ModelRegistryServiceAPIService) FindInferenceService(ctx context.Contex } // FindModelArtifact - Get a ModelArtifact that matches search parameters. -func (s *ModelRegistryServiceAPIService) FindModelArtifact(ctx context.Context, name string, externalID string) (ImplResponse, error) { - // TODO - update FindModelArtifact with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelArtifact{}) or use other options such as http.Ok ... - // return Response(200, ModelArtifact{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("FindModelArtifact method not implemented") +func (s *ModelRegistryServiceAPIService) FindModelArtifact(ctx context.Context, name string, externalID string, parentResourceID string) (ImplResponse, error) { + result, err := s.coreApi.GetModelArtifactByParams(&name, &externalID, &parentResourceID) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return esponse(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // FindModelVersion - Get a ModelVersion that matches search parameters. func (s *ModelRegistryServiceAPIService) FindModelVersion(ctx context.Context, name string, externalID string, registeredModelID string) (ImplResponse, error) { - // TODO - update FindModelVersion with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... - // return Response(200, ModelVersion{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("FindModelVersion method not implemented") + result, err := s.coreApi.GetModelVersionByParams(&name, &externalID, ®isteredModelID) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return esponse(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // FindRegisteredModel - Get a RegisteredModel that matches search parameters. func (s *ModelRegistryServiceAPIService) FindRegisteredModel(ctx context.Context, name string, externalID string) (ImplResponse, error) { - // TODO - update FindRegisteredModel with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... - // return Response(200, RegisteredModel{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("FindRegisteredModel method not implemented") + result, err := s.coreApi.GetRegisteredModelByParams(&name, &externalID) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return esponse(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // FindServingEnvironment - Find ServingEnvironment @@ -456,159 +409,152 @@ func (s *ModelRegistryServiceAPIService) GetInferenceServices(ctx context.Contex // GetModelArtifact - Get a ModelArtifact func (s *ModelRegistryServiceAPIService) GetModelArtifact(ctx context.Context, modelartifactId string) (ImplResponse, error) { - // TODO - update GetModelArtifact with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelArtifact{}) or use other options such as http.Ok ... - // return Response(200, ModelArtifact{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetModelArtifact method not implemented") + result, err := s.coreApi.GetModelArtifactById(modelartifactId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // GetModelArtifacts - List All ModelArtifacts func (s *ModelRegistryServiceAPIService) GetModelArtifacts(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetModelArtifacts with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelArtifactList{}) or use other options such as http.Ok ... - // return Response(200, ModelArtifactList{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetModelArtifacts method not implemented") + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetModelArtifacts(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }, nil) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetModelVersion - Get a ModelVersion func (s *ModelRegistryServiceAPIService) GetModelVersion(ctx context.Context, modelversionId string) (ImplResponse, error) { - // TODO - update GetModelVersion with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... - // return Response(200, ModelVersion{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetModelVersion method not implemented") + result, err := s.coreApi.GetModelVersionById(modelversionId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // GetModelVersionArtifacts - List All ModelVersion's artifacts func (s *ModelRegistryServiceAPIService) GetModelVersionArtifacts(ctx context.Context, modelversionId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetModelVersionArtifacts with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ArtifactList{}) or use other options such as http.Ok ... - // return Response(200, ArtifactList{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetModelVersionArtifacts method not implemented") + // TODO name unused + // TODO externalID unused + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetModelArtifacts(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }, &modelversionId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetModelVersions - List All ModelVersions func (s *ModelRegistryServiceAPIService) GetModelVersions(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetModelVersions with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelVersionList{}) or use other options such as http.Ok ... - // return Response(200, ModelVersionList{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetModelVersions method not implemented") + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetModelVersions(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }, nil) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetRegisteredModel - Get a RegisteredModel func (s *ModelRegistryServiceAPIService) GetRegisteredModel(ctx context.Context, registeredmodelId string) (ImplResponse, error) { - // TODO - update GetRegisteredModel with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... - // return Response(200, RegisteredModel{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetRegisteredModel method not implemented") + result, err := s.coreApi.GetRegisteredModelById(registeredmodelId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // GetRegisteredModelVersions - List All RegisteredModel's ModelVersions func (s *ModelRegistryServiceAPIService) GetRegisteredModelVersions(ctx context.Context, registeredmodelId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetRegisteredModelVersions with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelVersionList{}) or use other options such as http.Ok ... - // return Response(200, ModelVersionList{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetRegisteredModelVersions method not implemented") + // TODO name unused + // TODO externalID unused + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetModelVersions(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }, ®isteredmodelId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetRegisteredModels - List All RegisteredModels func (s *ModelRegistryServiceAPIService) GetRegisteredModels(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetRegisteredModels with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, RegisteredModelList{}) or use other options such as http.Ok ... - // return Response(200, RegisteredModelList{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetRegisteredModels method not implemented") + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetRegisteredModels(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetServingEnvironment - Get a ServingEnvironment @@ -673,71 +619,54 @@ func (s *ModelRegistryServiceAPIService) UpdateInferenceService(ctx context.Cont // UpdateModelArtifact - Update a ModelArtifact func (s *ModelRegistryServiceAPIService) UpdateModelArtifact(ctx context.Context, modelartifactId string, modelArtifactUpdate model.ModelArtifactUpdate) (ImplResponse, error) { - // TODO - update UpdateModelArtifact with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelArtifact{}) or use other options such as http.Ok ... - // return Response(200, ModelArtifact{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("UpdateModelArtifact method not implemented") + modelArtifact, err := s.converter.ConvertModelArtifactUpdate(&modelArtifactUpdate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + modelArtifact.Id = &modelartifactId + result, err := s.coreApi.UpsertModelArtifact(modelArtifact, nil) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // UpdateModelVersion - Update a ModelVersion func (s *ModelRegistryServiceAPIService) UpdateModelVersion(ctx context.Context, modelversionId string, modelVersion model.ModelVersion) (ImplResponse, error) { - // TODO - update UpdateModelVersion with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... - // return Response(200, ModelVersion{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("UpdateModelVersion method not implemented") + // TODO: this API is getting model.ModelVersion instead of model.ModelVersionUpdate. + // c, err := s.converter.ConvertModelVersionUpdate(&modelVersion) + // if err != nil { + // return Response(500, model.Error{Message: err.Error()}), nil + // } + // modelVersion.Id = &modelversionId + result, err := s.coreApi.UpsertModelVersion(&modelVersion, nil) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // UpdateRegisteredModel - Update a RegisteredModel func (s *ModelRegistryServiceAPIService) UpdateRegisteredModel(ctx context.Context, registeredmodelId string, registeredModelUpdate model.RegisteredModelUpdate) (ImplResponse, error) { - // TODO - update UpdateRegisteredModel with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... - // return Response(200, RegisteredModel{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("UpdateRegisteredModel method not implemented") + registeredModel, err := s.converter.ConvertRegisteredModelUpdate(®isteredModelUpdate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + registeredModel.Id = ®isteredmodelId + result, err := s.coreApi.UpsertRegisteredModel(registeredModel) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // UpdateServingEnvironment - Update a ServingEnvironment diff --git a/internal/server/openapi/routers.go b/internal/server/openapi/routers.go index 04881f7b..7846e445 100644 --- a/internal/server/openapi/routers.go +++ b/internal/server/openapi/routers.go @@ -12,15 +12,17 @@ package openapi import ( "encoding/json" "errors" - "github.com/go-chi/chi/v5" - "github.com/go-chi/chi/v5/middleware" - "github.com/golang/glog" "io" "mime/multipart" "net/http" "os" "strconv" "strings" + + "github.com/go-chi/chi/v5" + "github.com/go-chi/chi/v5/middleware" + "github.com/go-chi/cors" + "github.com/golang/glog" ) //lint:file-ignore U1000 Ignore all unused code, it's generated @@ -48,6 +50,14 @@ const errMsgMaxValueConstraint = "provided parameter is not respecting maximum v func NewRouter(routers ...Router) chi.Router { router := chi.NewRouter() router.Use(middleware.Logger) + router.Use(cors.Handler(cors.Options{ + AllowedOrigins: []string{"https://*", "http://*"}, + AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, + AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-PINGOTHER"}, + ExposedHeaders: []string{"Link"}, + AllowCredentials: false, + MaxAge: 300, // Maximum value not ignored by any of major browsers + })) for _, api := range routers { for _, route := range api.Routes() { handler := route.HandlerFunc diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go index 481efdb6..2aba64a0 100644 --- a/internal/server/openapi/type_asserts.go +++ b/internal/server/openapi/type_asserts.go @@ -5,8 +5,11 @@ * * API version: 1.0.0 * Generated by: OpenAPI Generator (https://openapi-generator.tech) + * */ +// File generated by scripts/gen_type_assert.sh - DO NOT EDIT + package openapi import ( @@ -15,15 +18,15 @@ import ( // AssertArtifactRequired checks if the required fields are not zero-ed func AssertArtifactRequired(obj model.Artifact) error { - elements := map[string]interface{}{ - "artifactType": obj.ModelArtifact.ArtifactType, - } - for name, el := range elements { - if isZero := IsZeroValue(el); isZero { - return &RequiredError{Field: name} - } - } - + // FIXME(manual): Artifact.ArtifactType is not present on client models + // elements := map[string]interface{}{ + // "artifactType": obj.ArtifactType, + // } + // for name, el := range elements { + // if isZero := IsZeroValue(el); isZero { + // return &RequiredError{Field: name} + // } + // } return nil } @@ -240,6 +243,16 @@ func AssertInferenceServiceCreateConstraints(obj model.InferenceServiceCreate) e // AssertInferenceServiceRequired checks if the required fields are not zero-ed func AssertInferenceServiceRequired(obj model.InferenceService) error { + elements := map[string]interface{}{ + "registeredModelId": obj.RegisteredModelId, + "servingEnvironmentId": obj.ServingEnvironmentId, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + return nil } @@ -284,6 +297,66 @@ func AssertInferenceServiceUpdateConstraints(obj model.InferenceServiceUpdate) e return nil } +// AssertMetadataBoolValueRequired checks if the required fields are not zero-ed +func AssertMetadataBoolValueRequired(obj model.MetadataBoolValue) error { + return nil +} + +// AssertMetadataBoolValueConstraints checks if the values respects the defined constraints +func AssertMetadataBoolValueConstraints(obj model.MetadataBoolValue) error { + return nil +} + +// AssertMetadataDoubleValueRequired checks if the required fields are not zero-ed +func AssertMetadataDoubleValueRequired(obj model.MetadataDoubleValue) error { + return nil +} + +// AssertMetadataDoubleValueConstraints checks if the values respects the defined constraints +func AssertMetadataDoubleValueConstraints(obj model.MetadataDoubleValue) error { + return nil +} + +// AssertMetadataIntValueRequired checks if the required fields are not zero-ed +func AssertMetadataIntValueRequired(obj model.MetadataIntValue) error { + return nil +} + +// AssertMetadataIntValueConstraints checks if the values respects the defined constraints +func AssertMetadataIntValueConstraints(obj model.MetadataIntValue) error { + return nil +} + +// AssertMetadataProtoValueRequired checks if the required fields are not zero-ed +func AssertMetadataProtoValueRequired(obj model.MetadataProtoValue) error { + return nil +} + +// AssertMetadataProtoValueConstraints checks if the values respects the defined constraints +func AssertMetadataProtoValueConstraints(obj model.MetadataProtoValue) error { + return nil +} + +// AssertMetadataStringValueRequired checks if the required fields are not zero-ed +func AssertMetadataStringValueRequired(obj model.MetadataStringValue) error { + return nil +} + +// AssertMetadataStringValueConstraints checks if the values respects the defined constraints +func AssertMetadataStringValueConstraints(obj model.MetadataStringValue) error { + return nil +} + +// AssertMetadataStructValueRequired checks if the required fields are not zero-ed +func AssertMetadataStructValueRequired(obj model.MetadataStructValue) error { + return nil +} + +// AssertMetadataStructValueConstraints checks if the values respects the defined constraints +func AssertMetadataStructValueConstraints(obj model.MetadataStructValue) error { + return nil +} + // AssertMetadataValueRequired checks if the required fields are not zero-ed func AssertMetadataValueRequired(obj model.MetadataValue) error { return nil diff --git a/patches/type_asserts.patch b/patches/type_asserts.patch new file mode 100644 index 00000000..4784fdc3 --- /dev/null +++ b/patches/type_asserts.patch @@ -0,0 +1,29 @@ +diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go +index 4318f15..2aba64a 100644 +--- a/internal/server/openapi/type_asserts.go ++++ b/internal/server/openapi/type_asserts.go +@@ -18,15 +18,15 @@ import ( + + // AssertArtifactRequired checks if the required fields are not zero-ed + func AssertArtifactRequired(obj model.Artifact) error { +- elements := map[string]interface{}{ +- "artifactType": obj.ArtifactType, +- } +- for name, el := range elements { +- if isZero := IsZeroValue(el); isZero { +- return &RequiredError{Field: name} +- } +- } +- ++ // FIXME(manual): Artifact.ArtifactType is not present on client models ++ // elements := map[string]interface{}{ ++ // "artifactType": obj.ArtifactType, ++ // } ++ // for name, el := range elements { ++ // if isZero := IsZeroValue(el); isZero { ++ // return &RequiredError{Field: name} ++ // } ++ // } + return nil + } + diff --git a/scripts/gen_type_asserts.sh b/scripts/gen_type_asserts.sh new file mode 100755 index 00000000..03f2a9ba --- /dev/null +++ b/scripts/gen_type_asserts.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +set -e + +ASSERT_FILE_PATH="internal/server/openapi/type_asserts.go" +PATCH="./patches/type_asserts.patch" + +# Remove the existing file identified by env.ASSERT_FILE_PATH +if [ -f "$ASSERT_FILE_PATH" ]; then + rm "$ASSERT_FILE_PATH" +fi + +# Create an empty file +touch "$ASSERT_FILE_PATH" + +INITIAL_CONTENT=$(cat < "$ASSERT_FILE_PATH" + +# Iterate over files starting with "model_" in the internal/server/openapi/ folder +for file in internal/server/openapi/model_*; do + # Check if the file is a regular file + if [ -f "$file" ]; then + # Ignore first 15 lines containing license, package and imports + sed -n '13,$p' "$file" >> "$ASSERT_FILE_PATH" + # Remove the merged file + rm "$file" + fi +done + +git apply "$PATCH" \ No newline at end of file diff --git a/templates/go-server/model.mustache b/templates/go-server/model.mustache new file mode 100644 index 00000000..111c0168 --- /dev/null +++ b/templates/go-server/model.mustache @@ -0,0 +1,112 @@ +{{>partial_header}} +package {{packageName}} + +{{#models}}{{#imports}} +{{#-first}}import ( +{{/-first}} "{{import}}"{{#-last}} +) +{{/-last}}{{/imports}} + +{{#model}} + +// Assert{{classname}}Required checks if the required fields are not zero-ed +func Assert{{classname}}Required(obj model.{{classname}}) error { +{{#hasRequired}} + elements := map[string]interface{}{ +{{#requiredVars}} "{{baseName}}": obj.{{name}}, +{{/requiredVars}} } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + +{{/hasRequired}} +{{#parent}} + {{^isMap}} + {{^isArray}} + if err := Assert{{{parent}}}Required(obj.{{{parent}}}); err != nil { + return err + } + + {{/isArray}} + {{/isMap}} +{{/parent}} +{{#Vars}} + {{#isNullable}} + {{#isModel}} + if obj.{{name}} != nil { + {{/isModel}} + {{#isArray}} + {{#items.isModel}} + if obj.{{name}} != nil { + {{/items.isModel}} + {{^items.isModel}} + {{#mostInnerItems.isModel}} + {{^mostInnerItems.isPrimitiveType}} + if obj.{{name}} != nil { + {{/mostInnerItems.isPrimitiveType}} + {{/mostInnerItems.isModel}} + {{/items.isModel}} + {{/isArray}} + {{/isNullable}} + {{#isModel}} +{{#isNullable}} {{/isNullable}} if err := Assert{{baseType}}Required({{#isNullable}}*{{/isNullable}}obj.{{name}}); err != nil { +{{#isNullable}} {{/isNullable}} return err +{{#isNullable}} {{/isNullable}} } + {{/isModel}} + {{#isArray}} + {{#items.isModel}} +{{#isNullable}} {{/isNullable}} for _, el := range {{#isNullable}}*{{/isNullable}}obj.{{name}} { +{{#isNullable}} {{/isNullable}} if err := Assert{{items.baseType}}Required(el); err != nil { +{{#isNullable}} {{/isNullable}} return err +{{#isNullable}} {{/isNullable}} } +{{#isNullable}} {{/isNullable}} } + {{/items.isModel}} + {{^items.isModel}} + {{#mostInnerItems.isModel}} + {{^mostInnerItems.isPrimitiveType}} +{{#isNullable}} {{/isNullable}} if err := AssertRecurseInterfaceRequired({{#isNullable}}*{{/isNullable}}obj.{{name}}, Assert{{mostInnerItems.dataType}}Required); err != nil { +{{#isNullable}} {{/isNullable}} return err +{{#isNullable}} {{/isNullable}} } + {{/mostInnerItems.isPrimitiveType}} + {{/mostInnerItems.isModel}} + {{/items.isModel}} + {{/isArray}} + {{#isNullable}} + {{#isModel}} + } + {{/isModel}} + {{#isArray}} + {{#items.isModel}} + } + {{/items.isModel}} + {{^items.isModel}} + {{#mostInnerItems.isModel}} + {{^mostInnerItems.isPrimitiveType}} + } + {{/mostInnerItems.isPrimitiveType}} + {{/mostInnerItems.isModel}} + {{/items.isModel}} + {{/isArray}} + {{/isNullable}} +{{/Vars}} + return nil +} + +// Assert{{classname}}Constraints checks if the values respects the defined constraints +func Assert{{classname}}Constraints(obj model.{{classname}}) error { +{{#Vars}} +{{#minimum}} + if {{#isNullable}}obj.{{name}} != nil && *{{/isNullable}}obj.{{name}} < {{minimum}} { + return &ParsingError{Err: errors.New(errMsgMinValueConstraint)} + } +{{/minimum}} +{{#maximum}} + if {{#isNullable}}obj.{{name}} != nil && *{{/isNullable}}obj.{{name}} > {{maximum}} { + return &ParsingError{Err: errors.New(errMsgMaxValueConstraint)} + } +{{/maximum}} +{{/Vars}} + return nil +}{{/model}}{{/models}} \ No newline at end of file diff --git a/test/robot/MLMetadata.py b/test/robot/MLMetadata.py new file mode 100644 index 00000000..fdae3f20 --- /dev/null +++ b/test/robot/MLMetadata.py @@ -0,0 +1,10 @@ +from ml_metadata.metadata_store import metadata_store +from ml_metadata.proto import metadata_store_pb2 + +class MLMetadata(metadata_store.MetadataStore): + def __init__(self, host: str = 'localhost', port: int = 8081): + client_connection_config = metadata_store_pb2.MetadataStoreClientConfig() + client_connection_config.host = host + client_connection_config.port = port + print(client_connection_config) + super().__init__(client_connection_config) diff --git a/test/robot/MRandLogicalModel.robot b/test/robot/MRandLogicalModel.robot new file mode 100644 index 00000000..dbb45239 --- /dev/null +++ b/test/robot/MRandLogicalModel.robot @@ -0,0 +1,56 @@ +*** Settings *** +Library String +Resource MRviaREST.resource +Library MLMetadata.py + + +*** Comments *** +You can replace the underlying keyword definition to go via: +- REST entrypoint +- Python entrypoint +for example by changing the imported `Resource MRviaREST.resource` +with an alternative implementation, etc. + + +*** Test Cases *** +Verify basic logical mapping between MR and MLMD + Comment This test ensures basic logical mapping bewteen MR entities and MLMD entities + ... based on the MR logical mapping: + ... RegisteredModel shall result in a MLMD Context + ... ModelVersion shall result in a MLMD Context and parent Context(of RegisteredModel) + ... ModelArtifact shall result in a MLMD Artifact and Attribution(to the parent Context of ModelVersion) + + ${name}= Generate Random String 8 [LETTERS] + ${rId}= Given I create a RegisteredModel having name=${name} + ${vId}= And I create a child ModelVersion having registeredModelID=${rId} name=v1 + ${aId}= And I create a child ModelArtifact having modelversionId=${vId} uri=s3://12345 + ${rId}= Convert To Integer ${rId} + ${vId}= Convert To Integer ${vId} + ${aId} Convert To Integer ${aId} + + # RegisteredModel shall result in a MLMD Context + @{singList} Create List ${rId} + ${mlmdProto} Get Contexts By Id ${singList} + Log To Console ${mlmdProto[0]} + Should be equal ${mlmdProto[0].type} odh.RegisteredModel + Should be equal ${mlmdProto[0].name} ${name} + + # ModelVersion shall result in a MLMD Context and parent Context(of RegisteredModel) + @{singList} Create List ${vId} + ${mlmdProto} Get Contexts By Id ${singList} + Log To Console ${mlmdProto[0]} + Should be equal ${mlmdProto[0].type} odh.ModelVersion + Should be equal ${mlmdProto[0].name} ${rId}:v1 + ${mlmdProto} Get Parent Contexts By Context ${vId} + Should be equal ${mlmdProto[0].id} ${rId} + + # ModelArtifact shall result in a MLMD Artifact and Attribution(to the parent Context of ModelVersion) + ${aNamePrefix} Set Variable ${vId}: + @{singList} Create List ${aId} + ${mlmdProto} Get Artifacts By Id ${singList} + Log To Console ${mlmdProto[0]} + Should be equal ${mlmdProto[0].type} odh.ModelArtifact + Should Start With ${mlmdProto[0].name} ${aNamePrefix} + Should be equal ${mlmdProto[0].uri} s3://12345 + ${mlmdProto} Get Artifacts By Context ${vId} + Should be equal ${mlmdProto[0].id} ${aId} diff --git a/test/robot/MRviaPython.resource b/test/robot/MRviaPython.resource new file mode 100644 index 00000000..54bb5b58 --- /dev/null +++ b/test/robot/MRviaPython.resource @@ -0,0 +1,17 @@ +*** Keywords *** +I create a RegisteredModel having + [Arguments] ${name} + # TODO: implement keyword "I create a RegisteredModel having". + Fail Not Implemented + + +I create a child ModelVersion having + [Arguments] ${registeredModelID} ${name} + # TODO: implement keyword "I create a child ModelVersion having". + Fail Not Implemented + + +I create a child ModelArtifact having + [Arguments] ${modelversionId} ${uri} + # TODO: implement keyword "I create a child ModelArtifact having". + Fail Not Implemented diff --git a/test/robot/MRviaREST.resource b/test/robot/MRviaREST.resource new file mode 100644 index 00000000..8b2d1cfa --- /dev/null +++ b/test/robot/MRviaREST.resource @@ -0,0 +1,52 @@ +*** Settings *** +Library RequestsLibrary +Library String + +*** Variables *** +${mr_host} localhost + +*** Keywords *** +I create a RegisteredModel having + [Arguments] ${name} + ${data}= Create Dictionary name=${name} + ${resp}= POST url=http://${mr_host}:8080/api/model_registry/v1alpha1/registered_models json=${data} expected_status=201 + Log to console ${resp.json()} + [return] ${resp.json()["id"]} + + +I create a child ModelVersion having + [Arguments] ${registeredModelID} ${name} + ${data}= Create Dictionary name=${name} registeredModelID=${registeredModelID} + ${resp}= POST url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_versions json=${data} expected_status=201 + Log to console ${resp.json()} + [return] ${resp.json()["id"]} + +I create a child ModelArtifact having + [Arguments] ${modelversionId} ${uri} + ${data}= Create Dictionary uri=${uri} artifactType=model-artifact + Log to console ${data} + ${resp}= POST url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_versions/${modelversionId}/artifacts json=${data} expected_status=201 + Log to console ${resp.json()} + [return] ${resp.json()["id"]} + + +I get RegisteredModelByID + [Arguments] ${id} + ${resp}= GET url=http://${mr_host}:8080/api/model_registry/v1alpha1/registered_models/${id} expected_status=200 + Log to console ${resp.json()} + [return] ${resp.json()} + + +I get ModelVersionByID + [Arguments] ${id} + ${resp}= GET url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_versions/${id} expected_status=200 + Log to console ${resp.json()} + [return] ${resp.json()} + + +I get ModelArtifactByID + [Arguments] ${id} + ${resp}= GET url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_artifacts/${id} expected_status=200 + Log to console ${resp.json()} + [return] ${resp.json()} + diff --git a/test/robot/UserStory.robot b/test/robot/UserStory.robot new file mode 100644 index 00000000..40606145 --- /dev/null +++ b/test/robot/UserStory.robot @@ -0,0 +1,20 @@ +*** Settings *** +Resource MRviaREST.resource + + +*** Comments *** +These User Story(-ies) are defined in the PM document + + +*** Test Cases *** +As a MLOps engineer I would like to store Model name + ${name}= Generate Random String 8 [LETTERS] + ${rId}= Given I create a RegisteredModel having name=${name} + ${vId}= And I create a child ModelVersion having registeredModelID=${rId} name=v1 + ${aId}= And I create a child ModelArtifact having modelversionId=${vId} uri=s3://12345 + ${r}= Then I get RegisteredModelByID id=${rId} + And Should be equal ${r["name"]} ${name} + ${r}= Then I get ModelVersionByID id=${vId} + And Should be equal ${r["name"]} v1 + ${r}= Then I get ModelArtifactByID id=${aId} + And Should be equal ${r["uri"]} s3://12345 From 902d428bea35f36cd6b0c2b9879fb7df7ad2bb3b Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:22 -0300 Subject: [PATCH 101/254] py: create model registry client Create a Python module for the model registry. We'll use gRPC to communicate with a wrapper of the MLMD C++ server. For that, we'll use the MLMD Python module because of its simplified interface, but also define our own as we want to decouple from their implementation in the future. Signed-off-by: Isabella Basso do Amaral --- clients/python/.gitignore | 6 ++++++ clients/python/README.md | 3 +++ clients/python/poetry.lock | 7 +++++++ clients/python/pyproject.toml | 23 +++++++++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 clients/python/.gitignore create mode 100644 clients/python/README.md create mode 100644 clients/python/poetry.lock create mode 100644 clients/python/pyproject.toml diff --git a/clients/python/.gitignore b/clients/python/.gitignore new file mode 100644 index 00000000..43ca8441 --- /dev/null +++ b/clients/python/.gitignore @@ -0,0 +1,6 @@ +.mypy_cache/ +/.coverage* +/dist/ +/.nox/ +/.python-version +__pycache__/ diff --git a/clients/python/README.md b/clients/python/README.md new file mode 100644 index 00000000..c6fe16ae --- /dev/null +++ b/clients/python/README.md @@ -0,0 +1,3 @@ +# Model Registry Python Client + +⚠️ This is still under construction. diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock new file mode 100644 index 00000000..4d28f692 --- /dev/null +++ b/clients/python/poetry.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +package = [] + +[metadata] +lock-version = "2.0" +python-versions = ">= 3.9, < 3.11" +content-hash = "8b14dbeb808ca6edb4d79da14544148aa8c98f7e46ccb0d719e6ca64885daf19" diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml new file mode 100644 index 00000000..8fc54f32 --- /dev/null +++ b/clients/python/pyproject.toml @@ -0,0 +1,23 @@ +[tool.poetry] +name = "model-registry" +version = "0.0.0" +description = "Client for Red Hat OpenDataHub Model Registry" +authors = ["Isabella Basso do Amaral "] +license = "Apache-2.0" +readme = "README.md" + +[tool.poetry.dependencies] +python = ">= 3.9, < 3.11" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.black] +line-length = 119 + +[tool.ruff] +ignore = ["E501"] + +[tool.ruff.mccabe] +max-complexity = 8 From bafef820fbba88ca9bb15021f1424b7d8e31f449 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:22 -0300 Subject: [PATCH 102/254] py: define base MLMD proto types for model registration Models are artifacts, but when versioned we want to associate them with other artifacts that belong together and compose a deployable unit. As a first implementation, let's not concern with other specific types of artifacts. Signed-off-by: Isabella Basso do Amaral --- clients/python/.gitignore | 1 + clients/python/README.md | 31 +- clients/python/docs/conf.py | 36 + clients/python/docs/index.md | 15 + clients/python/docs/reference.md | 7 + clients/python/noxfile.py | 59 ++ clients/python/poetry.lock | 769 +++++++++++++++++- clients/python/pyproject.toml | 6 + clients/python/src/model_registry/__init__.py | 3 + .../src/model_registry/types/__init__.py | 14 + .../src/model_registry/types/artifacts.py | 72 ++ .../python/src/model_registry/types/base.py | 30 + .../src/model_registry/types/contexts.py | 67 ++ 13 files changed, 1107 insertions(+), 3 deletions(-) create mode 100644 clients/python/docs/conf.py create mode 100644 clients/python/docs/index.md create mode 100644 clients/python/docs/reference.md create mode 100644 clients/python/noxfile.py create mode 100644 clients/python/src/model_registry/__init__.py create mode 100644 clients/python/src/model_registry/types/__init__.py create mode 100644 clients/python/src/model_registry/types/artifacts.py create mode 100644 clients/python/src/model_registry/types/base.py create mode 100644 clients/python/src/model_registry/types/contexts.py diff --git a/clients/python/.gitignore b/clients/python/.gitignore index 43ca8441..8c3b53c5 100644 --- a/clients/python/.gitignore +++ b/clients/python/.gitignore @@ -1,6 +1,7 @@ .mypy_cache/ /.coverage* /dist/ +/docs/_build/ /.nox/ /.python-version __pycache__/ diff --git a/clients/python/README.md b/clients/python/README.md index c6fe16ae..e31e07de 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -1,3 +1,32 @@ # Model Registry Python Client -⚠️ This is still under construction. +[![Python](https://img.shields.io/badge/python%20-3.9%7C3.10-blue)](https://github.com/opendatahub-io/model-registry) +[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](../../../LICENSE) + +This library provides a low level interface for interacting with a model registry server. + +Types are based on [ML Metadata](https://github.com/google/ml-metadata), with Pythonic class wrappers. + +## Basic usage + +Registry objects can be created by doing + + + + +```py +from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel + +trained_model = ModelArtifact("my_model_name", "resource_URI", + description="Model description") + +version = ModelVersion(trained_model, "v1.0", "model author") + +model = RegisteredModel("my_model_name") +``` + +## Development + +To build the documentation, run `nox -s docs-build`. + + diff --git a/clients/python/docs/conf.py b/clients/python/docs/conf.py new file mode 100644 index 00000000..11886ea7 --- /dev/null +++ b/clients/python/docs/conf.py @@ -0,0 +1,36 @@ +"""Sphinx configuration.""" + +project = "model-registry" +author = "Isabella Basso do Amaral" +copyright = f"2023, {author}" +html_theme = "furo" +extensions = [ + "sphinx.ext.autodoc", # support for automatic documentation + "sphinx.ext.napoleon", # support for NumPy and Google style docstrings + "sphinx.ext.todo", # support for TODOs on docstrings + "sphinx.ext.viewcode", # Add links to highlighted source code + "myst_parser", # Markdown support +] +autodoc_typehints = "signature" +napoleon_google_docstring = True +napoleon_use_param = True +napoleon_use_rtype = True + +autodoc_default_options = { + "members": True, + "show-inheritance": True, + "inherited-members": True, + "member-order": "bysource", +} + +# https://myst-parser.readthedocs.io/en/latest/syntax/optional.html +myst_enable_extensions = [ + "strikethrough", # enable ~~strikethrough~~ + "smartquotes", # converts quotes to “ ” ‘ ’ + "replacements", # converts symbols like (c), (tm), (r), --, ---, +- + "colon_fence", # use ::: to delimit a myst block + "linkify", # automatically create links for URLs + "deflist", # enables less verbose definition lists +] +myst_heading_anchors = 3 # automatically create anchors for headings up to h3 (###) +myst_linkify_fuzzy_links = False # only linkify schema-prefixed URLs (e.g. https://*) diff --git a/clients/python/docs/index.md b/clients/python/docs/index.md new file mode 100644 index 00000000..f77e9a9a --- /dev/null +++ b/clients/python/docs/index.md @@ -0,0 +1,15 @@ +```{include} ../README.md +--- +end-before: +--- +``` + +## Full Table of Contents + +```{toctree} +--- +maxdepth: 2 +--- + +reference +``` diff --git a/clients/python/docs/reference.md b/clients/python/docs/reference.md new file mode 100644 index 00000000..d141fe30 --- /dev/null +++ b/clients/python/docs/reference.md @@ -0,0 +1,7 @@ +# API Reference + +## Types + +```{eval-rst} +.. automodule:: model_registry.types +``` diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py new file mode 100644 index 00000000..bf630a4e --- /dev/null +++ b/clients/python/noxfile.py @@ -0,0 +1,59 @@ +"""Nox sessions.""" +import os +import shutil +import sys +from pathlib import Path +from textwrap import dedent + +import nox + + +try: + from nox_poetry import Session, session +except ImportError: + message = f"""\ + Nox failed to import the 'nox-poetry' package. + + Please install it using the following command: + + {sys.executable} -m pip install nox-poetry""" + raise SystemExit(dedent(message)) from None + + +package = "model_registry" +python_versions = ["3.10", "3.9"] +nox.needs_version = ">= 2021.6.6" +nox.options.sessions = ("docs-build",) + + +@session(name="docs-build", python=python_versions[0]) +def docs_build(session: Session) -> None: + """Build the documentation.""" + args = session.posargs or ["docs", "docs/_build"] + if not session.posargs and "FORCE_COLOR" in os.environ: + args.insert(0, "--color") + + session.install(".") + session.install("sphinx", "furo", "myst-parser", "linkify-it-py") + + build_dir = Path("docs", "_build") + if build_dir.exists(): + shutil.rmtree(build_dir) + + session.run("sphinx-build", *args) + + +@session(python=python_versions[0]) +def docs(session: Session) -> None: + """Build and serve the documentation with live reloading on file changes.""" + args = session.posargs or ["--open-browser", "docs", "docs/_build"] + session.install(".") + session.install( + "sphinx", "furo", "myst-parser", "linkify-it-py", "sphinx-autobuild" + ) + + build_dir = Path("docs", "_build") + if build_dir.exists(): + shutil.rmtree(build_dir) + + session.run("sphinx-autobuild", *args) diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock index 4d28f692..a80f7daa 100644 --- a/clients/python/poetry.lock +++ b/clients/python/poetry.lock @@ -1,7 +1,772 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. -package = [] + +[[package]] +name = "alabaster" +version = "0.7.13" +description = "A configurable sidebar-enabled Sphinx theme" +optional = false +python-versions = ">=3.6" +files = [ + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, +] + +[[package]] +name = "attrs" +version = "21.4.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, + {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, +] + +[package.extras] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"] +tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"] + +[[package]] +name = "babel" +version = "2.13.1" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"}, + {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "beautifulsoup4" +version = "4.12.2" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, + {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "certifi" +version = "2023.7.22" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] + +[[package]] +name = "charset-normalizer" +version = "3.3.1" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.1.tar.gz", hash = "sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-win32.whl", hash = "sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f"}, + {file = "charset_normalizer-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-win32.whl", hash = "sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8"}, + {file = "charset_normalizer-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-win32.whl", hash = "sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61"}, + {file = "charset_normalizer-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63a6f59e2d01310f754c270e4a257426fe5a591dc487f1983b3bbe793cf6bac6"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d6bfc32a68bc0933819cfdfe45f9abc3cae3877e1d90aac7259d57e6e0f85b1"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f3100d86dcd03c03f7e9c3fdb23d92e32abbca07e7c13ebd7ddfbcb06f5991f"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39b70a6f88eebe239fa775190796d55a33cfb6d36b9ffdd37843f7c4c1b5dc67"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e12f8ee80aa35e746230a2af83e81bd6b52daa92a8afaef4fea4a2ce9b9f4fa"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b6cefa579e1237ce198619b76eaa148b71894fb0d6bcf9024460f9bf30fd228"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:61f1e3fb621f5420523abb71f5771a204b33c21d31e7d9d86881b2cffe92c47c"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4f6e2a839f83a6a76854d12dbebde50e4b1afa63e27761549d006fa53e9aa80e"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:1ec937546cad86d0dce5396748bf392bb7b62a9eeb8c66efac60e947697f0e58"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:82ca51ff0fc5b641a2d4e1cc8c5ff108699b7a56d7f3ad6f6da9dbb6f0145b48"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:633968254f8d421e70f91c6ebe71ed0ab140220469cf87a9857e21c16687c034"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-win32.whl", hash = "sha256:c0c72d34e7de5604df0fde3644cc079feee5e55464967d10b24b1de268deceb9"}, + {file = "charset_normalizer-3.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:63accd11149c0f9a99e3bc095bbdb5a464862d77a7e309ad5938fbc8721235ae"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5a3580a4fdc4ac05f9e53c57f965e3594b2f99796231380adb2baaab96e22761"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2465aa50c9299d615d757c1c888bc6fef384b7c4aec81c05a0172b4400f98557"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb7cd68814308aade9d0c93c5bd2ade9f9441666f8ba5aa9c2d4b389cb5e2a45"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e43805ccafa0a91831f9cd5443aa34528c0c3f2cc48c4cb3d9a7721053874b"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:854cc74367180beb327ab9d00f964f6d91da06450b0855cbbb09187bcdb02de5"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c15070ebf11b8b7fd1bfff7217e9324963c82dbdf6182ff7050519e350e7ad9f"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4c99f98fc3a1835af8179dcc9013f93594d0670e2fa80c83aa36346ee763d2"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fb765362688821404ad6cf86772fc54993ec11577cd5a92ac44b4c2ba52155b"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dced27917823df984fe0c80a5c4ad75cf58df0fbfae890bc08004cd3888922a2"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a66bcdf19c1a523e41b8e9d53d0cedbfbac2e93c649a2e9502cb26c014d0980c"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ecd26be9f112c4f96718290c10f4caea6cc798459a3a76636b817a0ed7874e42"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f70fd716855cd3b855316b226a1ac8bdb3caf4f7ea96edcccc6f484217c9597"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:17a866d61259c7de1bdadef418a37755050ddb4b922df8b356503234fff7932c"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-win32.whl", hash = "sha256:548eefad783ed787b38cb6f9a574bd8664468cc76d1538215d510a3cd41406cb"}, + {file = "charset_normalizer-3.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:45f053a0ece92c734d874861ffe6e3cc92150e32136dd59ab1fb070575189c97"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-win32.whl", hash = "sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4"}, + {file = "charset_normalizer-3.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727"}, + {file = "charset_normalizer-3.3.1-py3-none-any.whl", hash = "sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "docutils" +version = "0.20.1" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, +] + +[[package]] +name = "furo" +version = "2023.9.10" +description = "A clean customisable Sphinx documentation theme." +optional = false +python-versions = ">=3.8" +files = [ + {file = "furo-2023.9.10-py3-none-any.whl", hash = "sha256:513092538537dc5c596691da06e3c370714ec99bc438680edc1debffb73e5bfc"}, + {file = "furo-2023.9.10.tar.gz", hash = "sha256:5707530a476d2a63b8cad83b4f961f3739a69f4b058bcf38a03a39fa537195b2"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +pygments = ">=2.7" +sphinx = ">=6.0,<8.0" +sphinx-basic-ng = "*" + +[[package]] +name = "idna" +version = "3.4" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +description = "Getting image size from png/jpeg/jpeg2000/gif file" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"}, + {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, +] + +[[package]] +name = "importlib-metadata" +version = "6.8.0" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, + {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "linkify-it-py" +version = "2.0.2" +description = "Links recognition library with FULL unicode support." +optional = false +python-versions = ">=3.7" +files = [ + {file = "linkify-it-py-2.0.2.tar.gz", hash = "sha256:19f3060727842c254c808e99d465c80c49d2c7306788140987a1a7a29b0d6ad2"}, + {file = "linkify_it_py-2.0.2-py3-none-any.whl", hash = "sha256:a3a24428f6c96f27370d7fe61d2ac0be09017be5190d68d8658233171f1b6541"}, +] + +[package.dependencies] +uc-micro-py = "*" + +[package.extras] +benchmark = ["pytest", "pytest-benchmark"] +dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] +doc = ["myst-parser", "sphinx", "sphinx-book-theme"] +test = ["coverage", "pytest", "pytest-cov"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.4.0" +description = "Collection of plugins for markdown-it-py" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mdit_py_plugins-0.4.0-py3-none-any.whl", hash = "sha256:b51b3bb70691f57f974e257e367107857a93b36f322a9e6d44ca5bf28ec2def9"}, + {file = "mdit_py_plugins-0.4.0.tar.gz", hash = "sha256:d8ab27e9aed6c38aa716819fedfde15ca275715955f8a185a8e1cf90fb1d2c1b"}, +] + +[package.dependencies] +markdown-it-py = ">=1.0.0,<4.0.0" + +[package.extras] +code-style = ["pre-commit"] +rtd = ["myst-parser", "sphinx-book-theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "myst-parser" +version = "2.0.0" +description = "An extended [CommonMark](https://spec.commonmark.org/) compliant parser," +optional = false +python-versions = ">=3.8" +files = [ + {file = "myst_parser-2.0.0-py3-none-any.whl", hash = "sha256:7c36344ae39c8e740dad7fdabf5aa6fc4897a813083c6cc9990044eb93656b14"}, + {file = "myst_parser-2.0.0.tar.gz", hash = "sha256:ea929a67a6a0b1683cdbe19b8d2e724cd7643f8aa3e7bb18dd65beac3483bead"}, +] + +[package.dependencies] +docutils = ">=0.16,<0.21" +jinja2 = "*" +linkify-it-py = {version = ">=2.0,<3.0", optional = true, markers = "extra == \"linkify\""} +markdown-it-py = ">=3.0,<4.0" +mdit-py-plugins = ">=0.4,<1.0" +pyyaml = "*" +sphinx = ">=6,<8" + +[package.extras] +code-style = ["pre-commit (>=3.0,<4.0)"] +linkify = ["linkify-it-py (>=2.0,<3.0)"] +rtd = ["ipython", "pydata-sphinx-theme (==v0.13.0rc4)", "sphinx-autodoc2 (>=0.4.2,<0.5.0)", "sphinx-book-theme (==1.0.0rc2)", "sphinx-copybutton", "sphinx-design2", "sphinx-pyscript", "sphinx-tippy (>=0.3.1)", "sphinx-togglebutton", "sphinxext-opengraph (>=0.8.2,<0.9.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"] +testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=7,<8)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx-pytest"] +testing-docutils = ["pygments", "pytest (>=7,<8)", "pytest-param-files (>=0.3.4,<0.4.0)"] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pygments" +version = "2.16.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, + {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, +] + +[package.extras] +plugins = ["importlib-metadata"] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." +optional = false +python-versions = "*" +files = [ + {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, + {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, +] + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "sphinx" +version = "7.2.6" +description = "Python documentation generator" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"}, + {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"}, +] + +[package.dependencies] +alabaster = ">=0.7,<0.8" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.18.1,<0.21" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.14" +requests = ">=2.25.0" +snowballstemmer = ">=2.0" +sphinxcontrib-applehelp = "*" +sphinxcontrib-devhelp = "*" +sphinxcontrib-htmlhelp = ">=2.0.0" +sphinxcontrib-jsmath = "*" +sphinxcontrib-qthelp = "*" +sphinxcontrib-serializinghtml = ">=1.1.9" + +[package.extras] +docs = ["sphinxcontrib-websupport"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] +test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +description = "A modern skeleton for Sphinx themes." +optional = false +python-versions = ">=3.7" +files = [ + {file = "sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b"}, + {file = "sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9"}, +] + +[package.dependencies] +sphinx = ">=4.0" + +[package.extras] +docs = ["furo", "ipython", "myst-parser", "sphinx-copybutton", "sphinx-inline-tabs"] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "1.0.7" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"}, + {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"}, +] + +[package.dependencies] +Sphinx = ">=5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "1.0.5" +description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"}, + {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"}, +] + +[package.dependencies] +Sphinx = ">=5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.0.4" +description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"}, + {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"}, +] + +[package.dependencies] +Sphinx = ">=5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["html5lib", "pytest"] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +description = "A sphinx extension which renders display math in HTML via JavaScript" +optional = false +python-versions = ">=3.5" +files = [ + {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, + {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, +] + +[package.extras] +test = ["flake8", "mypy", "pytest"] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "1.0.6" +description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"}, + {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"}, +] + +[package.dependencies] +Sphinx = ">=5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "1.1.9" +description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" +optional = false +python-versions = ">=3.9" +files = [ + {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"}, + {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"}, +] + +[package.dependencies] +Sphinx = ">=5" + +[package.extras] +lint = ["docutils-stubs", "flake8", "mypy"] +test = ["pytest"] + +[[package]] +name = "uc-micro-py" +version = "1.0.2" +description = "Micro subset of unicode data files for linkify-it-py projects." +optional = false +python-versions = ">=3.7" +files = [ + {file = "uc-micro-py-1.0.2.tar.gz", hash = "sha256:30ae2ac9c49f39ac6dce743bd187fcd2b574b16ca095fa74cd9396795c954c54"}, + {file = "uc_micro_py-1.0.2-py3-none-any.whl", hash = "sha256:8c9110c309db9d9e87302e2f4ad2c3152770930d88ab385cd544e7a7e75f3de0"}, +] + +[package.extras] +test = ["coverage", "pytest", "pytest-cov"] + +[[package]] +name = "urllib3" +version = "2.0.7" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ + {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, + {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "zipp" +version = "3.17.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 3.11" -content-hash = "8b14dbeb808ca6edb4d79da14544148aa8c98f7e46ccb0d719e6ca64885daf19" +content-hash = "8fe91bb06d76f41b5c50719a8374a8efda1232b1c7d04585807ed226106640d7" diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 8fc54f32..d2f404cf 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -8,6 +8,12 @@ readme = "README.md" [tool.poetry.dependencies] python = ">= 3.9, < 3.11" +attrs = "^21.0" + +[tool.poetry.group.dev.dependencies] +sphinx = "^7.2.6" +furo = "^2023.9.10" +myst-parser = { extras = ["linkify"], version = "^2.0.0" } [build-system] requires = ["poetry-core"] diff --git a/clients/python/src/model_registry/__init__.py b/clients/python/src/model_registry/__init__.py new file mode 100644 index 00000000..85f20d12 --- /dev/null +++ b/clients/python/src/model_registry/__init__.py @@ -0,0 +1,3 @@ +"""Main package for the ODH model registry.""" + +__version__ = "0.0.0" diff --git a/clients/python/src/model_registry/types/__init__.py b/clients/python/src/model_registry/types/__init__.py new file mode 100644 index 00000000..e2892122 --- /dev/null +++ b/clients/python/src/model_registry/types/__init__.py @@ -0,0 +1,14 @@ +"""Model registry types. +""" + +from .artifacts import ModelArtifact, ArtifactState +from .contexts import ModelVersion, RegisteredModel + +__all__ = [ + # Artifacts + "ModelArtifact", + "ArtifactState", + # Contexts + "ModelVersion", + "RegisteredModel", +] diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py new file mode 100644 index 00000000..c2296036 --- /dev/null +++ b/clients/python/src/model_registry/types/artifacts.py @@ -0,0 +1,72 @@ +"""Artifact types for model registry. + +Artifacts represent pieces of data. +This could be datasets, models, metrics, or any other piece of data produced or consumed by an +execution, such as an experiment run. + +Those types are used to map between proto types based on artifacts and Python objects. + +TODO: + * Move part of the description to API Reference docs (#120). +""" + +from enum import Enum, unique +from typing import Optional + +from attrs import define, field + +from .base import ProtoBase + + +@unique +class ArtifactState(Enum): + """State of an artifact.""" + + UNKNOWN = 0 + PENDING = 1 + LIVE = 2 + MARKED_FOR_DELETION = 3 + DELETED = 4 + ABANDONED = 5 + REFERENCE = 6 + + +@define(slots=False) +class BaseArtifact(ProtoBase): + """Abstract base class for all artifacts. + + Attributes: + name (str): Name of the artifact. + uri (str): URI of the artifact. + state (ArtifactState): State of the artifact. + """ + + name: str + uri: str + state: ArtifactState = field(init=False, default=ArtifactState.UNKNOWN) + + +@define(slots=False) +class ModelArtifact(BaseArtifact): + """Represents a Model. + + Attributes: + name (str): Name of the model. + uri (str): URI of the model. + description (str, optional): Description of the object. + external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. + model_format_name (str, optional): Name of the model format. + model_format_version (str, optional): Version of the model format. + runtime (str, optional): Runtime of the model. + storage_key (str, optional): Storage key of the model. + storage_path (str, optional): Storage path of the model. + service_account_name (str, optional): Service account name of the model. + """ + + # TODO: this could be an enum of valid formats + model_format_name: Optional[str] = field(kw_only=True, default=None) + model_format_version: Optional[str] = field(kw_only=True, default=None) + runtime: Optional[str] = field(kw_only=True, default=None) + storage_key: Optional[str] = field(kw_only=True, default=None) + storage_path: Optional[str] = field(kw_only=True, default=None) + service_account_name: Optional[str] = field(kw_only=True, default=None) diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py new file mode 100644 index 00000000..80a4babb --- /dev/null +++ b/clients/python/src/model_registry/types/base.py @@ -0,0 +1,30 @@ +"""Base type for protos""" + +from abc import ABC +from typing import Optional + +from attrs import define, field + + +@define(slots=False, init=False) +class ProtoBase(ABC): + """Abstract base type for protos + + This is a type defining common functionality for all types representing Model Registry protos, + such as Artifacts, Contexts, and Executions. + + Attributes: + id (str): Protobuf object ID. Auto-assigned when put on the server. + name (str): Name of the object. + description (str, optional): Description of the object. + external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. + create_time_since_epoch (int): Seconds elapsed since object creation time, measured against epoch. + last_update_time_since_epoch (int): Seconds elapsed since object last update time, measured against epoch. + """ + + name: str = field(init=False) + id: Optional[str] = field(init=False, default=None) + description: str = field(kw_only=True) + external_id: Optional[str] = field(kw_only=True, default=None) + create_time_since_epoch: Optional[int] = field(init=False, default=None) + last_update_time_since_epoch: Optional[int] = field(init=False, default=None) diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py new file mode 100644 index 00000000..46dffce4 --- /dev/null +++ b/clients/python/src/model_registry/types/contexts.py @@ -0,0 +1,67 @@ +"""Context types for model registry. + +Contexts group related Artifacts together. +They provide a way to organize and categorize components in a workflow. + +Those types are used to map between proto types based on contexts and Python objects. + +TODO: + * Move part of the description to API Reference docs (#120). +""" + +from abc import ABC +from typing import Union + +from .artifacts import BaseArtifact, ModelArtifact +from .base import ProtoBase + +from attrs import define, field + + +ScalarType = Union[str, int, float, bool] + + +@define(slots=False, init=False) +class BaseContext(ProtoBase, ABC): + """Abstract base class for all contexts.""" + + +@define(slots=False) +class ModelVersion(BaseContext): + """Represents a model version. + + Attributes: + model (ModelArtifact): Model associated with this version. + version (str): Version of the model. + author (str): Author of the model version. + description (str, optional): Description of the object. + external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. + artifacts (list[BaseArtifact]): Artifacts associated with this version. + tags (list[str]): Tags associated with this version. + metadata (dict[str, ScalarType]): Metadata associated with this version. + """ + + model: ModelArtifact + version: str + author: str + artifacts: list[BaseArtifact] = field(init=False, factory=list) + tags: list[str] = field(init=False, factory=list) + metadata: dict[str, ScalarType] = field(init=False, factory=dict) + + def __attrs_post_init__(self) -> None: + self.name = self.version + + +@define(slots=False) +class RegisteredModel(BaseContext): + """Represents a registered model. + + Attributes: + name (str): Registered model name. + description (str, optional): Description of the object. + external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. + versions (list[ModelVersion]): Versions associated with this model. + """ + + name: str + versions: list[ModelVersion] = field(init=False, factory=list) From 8c19bd8cb0af2202fc77b272db1a0d0669bc6768 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:23 -0300 Subject: [PATCH 103/254] py: add Mappable interface and test implementers We want to be able to map those types to the MLMD gRPC types, so let's use a interface to keep the fiddly data manipulation close to the data. Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 4 +- clients/python/noxfile.py | 30 +- clients/python/poetry.lock | 304 +++++++++++++++++- clients/python/pyproject.toml | 15 + .../src/model_registry/types/artifacts.py | 70 +++- .../python/src/model_registry/types/base.py | 126 +++++++- .../src/model_registry/types/contexts.py | 40 ++- clients/python/tests/__init__.py | 0 clients/python/tests/types/__init__.py | 7 + .../tests/types/test_artifact_mapping.py | 95 ++++++ .../tests/types/test_context_mapping.py | 92 ++++++ 11 files changed, 761 insertions(+), 22 deletions(-) create mode 100644 clients/python/tests/__init__.py create mode 100644 clients/python/tests/types/__init__.py create mode 100644 clients/python/tests/types/test_artifact_mapping.py create mode 100644 clients/python/tests/types/test_context_mapping.py diff --git a/clients/python/README.md b/clients/python/README.md index e31e07de..75f21091 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -27,6 +27,8 @@ model = RegisteredModel("my_model_name") ## Development -To build the documentation, run `nox -s docs-build`. +Common tasks, such as building documentation and running tests, can be executed using [`nox`](https://github.com/wntrblm/nox) sessions. + +Use `nox -l` to list sessions and execute them using `nox -s [session]`. diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py index bf630a4e..3ddae592 100644 --- a/clients/python/noxfile.py +++ b/clients/python/noxfile.py @@ -23,7 +23,35 @@ package = "model_registry" python_versions = ["3.10", "3.9"] nox.needs_version = ">= 2021.6.6" -nox.options.sessions = ("docs-build",) +nox.options.sessions = ( + "tests", + "docs-build", +) + + +@session(python=python_versions) +def tests(session: Session) -> None: + """Run the test suite.""" + session.install(".") + session.install("coverage[toml]", "pytest", "pygments") + try: + session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs) + finally: + if session.interactive: + session.notify("coverage", posargs=[]) + + +@session(python=python_versions[0]) +def coverage(session: Session) -> None: + """Produce the coverage report.""" + args = session.posargs or ["report"] + + session.install("coverage[toml]") + + if not session.posargs and any(Path().glob(".coverage.*")): + session.run("coverage", "combine") + + session.run("coverage", *args) @session(name="docs-build", python=python_versions[0]) diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock index a80f7daa..9431ea5e 100644 --- a/clients/python/poetry.lock +++ b/clients/python/poetry.lock @@ -1,5 +1,16 @@ # This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +[[package]] +name = "absl-py" +version = "1.4.0" +description = "Abseil Python Common Libraries, see https://github.com/abseil/abseil-py." +optional = false +python-versions = ">=3.6" +files = [ + {file = "absl-py-1.4.0.tar.gz", hash = "sha256:d2c244d01048ba476e7c080bd2c6df5e141d211de80223460d5b3b8a2a58433d"}, + {file = "absl_py-1.4.0-py3-none-any.whl", hash = "sha256:0d3fe606adfa4f7db64792dd4c7aee4ee0c38ab75dfd353b7a83ed3e957fcb47"}, +] + [[package]] name = "alabaster" version = "0.7.13" @@ -181,6 +192,73 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "coverage" +version = "7.3.2" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf"}, + {file = "coverage-7.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c"}, + {file = "coverage-7.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148"}, + {file = "coverage-7.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9"}, + {file = "coverage-7.3.2-cp310-cp310-win32.whl", hash = "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f"}, + {file = "coverage-7.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c"}, + {file = "coverage-7.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3"}, + {file = "coverage-7.3.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c"}, + {file = "coverage-7.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312"}, + {file = "coverage-7.3.2-cp311-cp311-win32.whl", hash = "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640"}, + {file = "coverage-7.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836"}, + {file = "coverage-7.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4"}, + {file = "coverage-7.3.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84"}, + {file = "coverage-7.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a"}, + {file = "coverage-7.3.2-cp312-cp312-win32.whl", hash = "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb"}, + {file = "coverage-7.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738"}, + {file = "coverage-7.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c"}, + {file = "coverage-7.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901"}, + {file = "coverage-7.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76"}, + {file = "coverage-7.3.2-cp38-cp38-win32.whl", hash = "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92"}, + {file = "coverage-7.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce"}, + {file = "coverage-7.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25"}, + {file = "coverage-7.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc"}, + {file = "coverage-7.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083"}, + {file = "coverage-7.3.2-cp39-cp39-win32.whl", hash = "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce"}, + {file = "coverage-7.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f"}, + {file = "coverage-7.3.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637"}, + {file = "coverage-7.3.2.tar.gz", hash = "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + [[package]] name = "docutils" version = "0.20.1" @@ -192,6 +270,20 @@ files = [ {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] +[[package]] +name = "exceptiongroup" +version = "1.1.3" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, +] + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "furo" version = "2023.9.10" @@ -209,6 +301,72 @@ pygments = ">=2.7" sphinx = ">=6.0,<8.0" sphinx-basic-ng = "*" +[[package]] +name = "grpcio" +version = "1.59.0" +description = "HTTP/2-based RPC framework" +optional = false +python-versions = ">=3.7" +files = [ + {file = "grpcio-1.59.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:225e5fa61c35eeaebb4e7491cd2d768cd8eb6ed00f2664fa83a58f29418b39fd"}, + {file = "grpcio-1.59.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b95ec8ecc4f703f5caaa8d96e93e40c7f589bad299a2617bdb8becbcce525539"}, + {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:1a839ba86764cc48226f50b924216000c79779c563a301586a107bda9cbe9dcf"}, + {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6cfe44a5d7c7d5f1017a7da1c8160304091ca5dc64a0f85bca0d63008c3137a"}, + {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0fcf53df684fcc0154b1e61f6b4a8c4cf5f49d98a63511e3f30966feff39cd0"}, + {file = "grpcio-1.59.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa66cac32861500f280bb60fe7d5b3e22d68c51e18e65367e38f8669b78cea3b"}, + {file = "grpcio-1.59.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8cd2d38c2d52f607d75a74143113174c36d8a416d9472415eab834f837580cf7"}, + {file = "grpcio-1.59.0-cp310-cp310-win32.whl", hash = "sha256:228b91ce454876d7eed74041aff24a8f04c0306b7250a2da99d35dd25e2a1211"}, + {file = "grpcio-1.59.0-cp310-cp310-win_amd64.whl", hash = "sha256:ca87ee6183421b7cea3544190061f6c1c3dfc959e0b57a5286b108511fd34ff4"}, + {file = "grpcio-1.59.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:c173a87d622ea074ce79be33b952f0b424fa92182063c3bda8625c11d3585d09"}, + {file = "grpcio-1.59.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:ec78aebb9b6771d6a1de7b6ca2f779a2f6113b9108d486e904bde323d51f5589"}, + {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:0b84445fa94d59e6806c10266b977f92fa997db3585f125d6b751af02ff8b9fe"}, + {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c251d22de8f9f5cca9ee47e4bade7c5c853e6e40743f47f5cc02288ee7a87252"}, + {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:956f0b7cb465a65de1bd90d5a7475b4dc55089b25042fe0f6c870707e9aabb1d"}, + {file = "grpcio-1.59.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:38da5310ef84e16d638ad89550b5b9424df508fd5c7b968b90eb9629ca9be4b9"}, + {file = "grpcio-1.59.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:63982150a7d598281fa1d7ffead6096e543ff8be189d3235dd2b5604f2c553e5"}, + {file = "grpcio-1.59.0-cp311-cp311-win32.whl", hash = "sha256:50eff97397e29eeee5df106ea1afce3ee134d567aa2c8e04fabab05c79d791a7"}, + {file = "grpcio-1.59.0-cp311-cp311-win_amd64.whl", hash = "sha256:15f03bd714f987d48ae57fe092cf81960ae36da4e520e729392a59a75cda4f29"}, + {file = "grpcio-1.59.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f1feb034321ae2f718172d86b8276c03599846dc7bb1792ae370af02718f91c5"}, + {file = "grpcio-1.59.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d09bd2a4e9f5a44d36bb8684f284835c14d30c22d8ec92ce796655af12163588"}, + {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:2f120d27051e4c59db2f267b71b833796770d3ea36ca712befa8c5fff5da6ebd"}, + {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0ca727a173ee093f49ead932c051af463258b4b493b956a2c099696f38aa66"}, + {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5711c51e204dc52065f4a3327dca46e69636a0b76d3e98c2c28c4ccef9b04c52"}, + {file = "grpcio-1.59.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d74f7d2d7c242a6af9d4d069552ec3669965b74fed6b92946e0e13b4168374f9"}, + {file = "grpcio-1.59.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3859917de234a0a2a52132489c4425a73669de9c458b01c9a83687f1f31b5b10"}, + {file = "grpcio-1.59.0-cp312-cp312-win32.whl", hash = "sha256:de2599985b7c1b4ce7526e15c969d66b93687571aa008ca749d6235d056b7205"}, + {file = "grpcio-1.59.0-cp312-cp312-win_amd64.whl", hash = "sha256:598f3530231cf10ae03f4ab92d48c3be1fee0c52213a1d5958df1a90957e6a88"}, + {file = "grpcio-1.59.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:b34c7a4c31841a2ea27246a05eed8a80c319bfc0d3e644412ec9ce437105ff6c"}, + {file = "grpcio-1.59.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:c4dfdb49f4997dc664f30116af2d34751b91aa031f8c8ee251ce4dcfc11277b0"}, + {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:61bc72a00ecc2b79d9695220b4d02e8ba53b702b42411397e831c9b0589f08a3"}, + {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f367e4b524cb319e50acbdea57bb63c3b717c5d561974ace0b065a648bb3bad3"}, + {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:849c47ef42424c86af069a9c5e691a765e304079755d5c29eff511263fad9c2a"}, + {file = "grpcio-1.59.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c0488c2b0528e6072010182075615620071371701733c63ab5be49140ed8f7f0"}, + {file = "grpcio-1.59.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:611d9aa0017fa386809bddcb76653a5ab18c264faf4d9ff35cb904d44745f575"}, + {file = "grpcio-1.59.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e5378785dce2b91eb2e5b857ec7602305a3b5cf78311767146464bfa365fc897"}, + {file = "grpcio-1.59.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:fe976910de34d21057bcb53b2c5e667843588b48bf11339da2a75f5c4c5b4055"}, + {file = "grpcio-1.59.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:c041a91712bf23b2a910f61e16565a05869e505dc5a5c025d429ca6de5de842c"}, + {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:0ae444221b2c16d8211b55326f8ba173ba8f8c76349bfc1768198ba592b58f74"}, + {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceb1e68135788c3fce2211de86a7597591f0b9a0d2bb80e8401fd1d915991bac"}, + {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c4b1cc3a9dc1924d2eb26eec8792fedd4b3fcd10111e26c1d551f2e4eda79ce"}, + {file = "grpcio-1.59.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:871371ce0c0055d3db2a86fdebd1e1d647cf21a8912acc30052660297a5a6901"}, + {file = "grpcio-1.59.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:93e9cb546e610829e462147ce724a9cb108e61647a3454500438a6deef610be1"}, + {file = "grpcio-1.59.0-cp38-cp38-win32.whl", hash = "sha256:f21917aa50b40842b51aff2de6ebf9e2f6af3fe0971c31960ad6a3a2b24988f4"}, + {file = "grpcio-1.59.0-cp38-cp38-win_amd64.whl", hash = "sha256:14890da86a0c0e9dc1ea8e90101d7a3e0e7b1e71f4487fab36e2bfd2ecadd13c"}, + {file = "grpcio-1.59.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:34341d9e81a4b669a5f5dca3b2a760b6798e95cdda2b173e65d29d0b16692857"}, + {file = "grpcio-1.59.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:986de4aa75646e963466b386a8c5055c8b23a26a36a6c99052385d6fe8aaf180"}, + {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:aca8a24fef80bef73f83eb8153f5f5a0134d9539b4c436a716256b311dda90a6"}, + {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:936b2e04663660c600d5173bc2cc84e15adbad9c8f71946eb833b0afc205b996"}, + {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc8bf2e7bc725e76c0c11e474634a08c8f24bcf7426c0c6d60c8f9c6e70e4d4a"}, + {file = "grpcio-1.59.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81d86a096ccd24a57fa5772a544c9e566218bc4de49e8c909882dae9d73392df"}, + {file = "grpcio-1.59.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2ea95cd6abbe20138b8df965b4a8674ec312aaef3147c0f46a0bac661f09e8d0"}, + {file = "grpcio-1.59.0-cp39-cp39-win32.whl", hash = "sha256:3b8ff795d35a93d1df6531f31c1502673d1cebeeba93d0f9bd74617381507e3f"}, + {file = "grpcio-1.59.0-cp39-cp39-win_amd64.whl", hash = "sha256:38823bd088c69f59966f594d087d3a929d1ef310506bee9e3648317660d65b81"}, + {file = "grpcio-1.59.0.tar.gz", hash = "sha256:acf70a63cf09dd494000007b798aff88a436e1c03b394995ce450be437b8e54f"}, +] + +[package.extras] +protobuf = ["grpcio-tools (>=1.59.0)"] + [[package]] name = "idna" version = "3.4" @@ -250,6 +408,17 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + [[package]] name = "jinja2" version = "3.1.2" @@ -410,6 +579,31 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] +[[package]] +name = "ml-metadata" +version = "1.14.0" +description = "A library for maintaining metadata for artifacts." +optional = false +python-versions = ">=3.8,<4" +files = [ + {file = "ml_metadata-1.14.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:50ef7c83e917f591639447e8b395fb97abded9a86be9afddab79b2155eb5a32c"}, + {file = "ml_metadata-1.14.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69bd8690c0c54a9332f4958ec4c541d44f994a7d7e382801fa242e63b182ec37"}, + {file = "ml_metadata-1.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:367e9bfe8449baed86242ba0ffc7956b0e8cac1d0bb0ccb296ff5634410fd07b"}, + {file = "ml_metadata-1.14.0-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:8823d01fa3488a6918ce8c7b318929b71aff0774c238b2426cc469d2ee115efd"}, + {file = "ml_metadata-1.14.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebaabd99c1028a98a947787a9d195b752c787270bc5105b2414cdefb0204c0d0"}, + {file = "ml_metadata-1.14.0-cp38-cp38-win_amd64.whl", hash = "sha256:b40be36440a63b40a4a788a40fbbe37c086cc89977867f10ae17150146474098"}, + {file = "ml_metadata-1.14.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:5671da7d3f765fb37d7c2a302d597ad0adeaf9655bf0e59dbe06ff7e9f6b155e"}, + {file = "ml_metadata-1.14.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92bdfccdfe3755ad1545ed052c84f47880713ce49e72a5fcc395ad6699ccedd9"}, + {file = "ml_metadata-1.14.0-cp39-cp39-win_amd64.whl", hash = "sha256:8dd44943c61716a9086635f24b75c3b18e1bee33cf5a600600616f0307400845"}, +] + +[package.dependencies] +absl-py = ">=0.9,<2.0.0" +attrs = ">=20.3,<22" +grpcio = ">=1.8.6,<2" +protobuf = ">=3.13,<4" +six = ">=1.10,<2" + [[package]] name = "myst-parser" version = "2.0.0" @@ -448,6 +642,52 @@ files = [ {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] +[[package]] +name = "pluggy" +version = "1.3.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "protobuf" +version = "3.20.3" +description = "Protocol Buffers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "protobuf-3.20.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:f4bd856d702e5b0d96a00ec6b307b0f51c1982c2bf9c0052cf9019e9a544ba99"}, + {file = "protobuf-3.20.3-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9aae4406ea63d825636cc11ffb34ad3379335803216ee3a856787bcf5ccc751e"}, + {file = "protobuf-3.20.3-cp310-cp310-win32.whl", hash = "sha256:28545383d61f55b57cf4df63eebd9827754fd2dc25f80c5253f9184235db242c"}, + {file = "protobuf-3.20.3-cp310-cp310-win_amd64.whl", hash = "sha256:67a3598f0a2dcbc58d02dd1928544e7d88f764b47d4a286202913f0b2801c2e7"}, + {file = "protobuf-3.20.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:899dc660cd599d7352d6f10d83c95df430a38b410c1b66b407a6b29265d66469"}, + {file = "protobuf-3.20.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e64857f395505ebf3d2569935506ae0dfc4a15cb80dc25261176c784662cdcc4"}, + {file = "protobuf-3.20.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:d9e4432ff660d67d775c66ac42a67cf2453c27cb4d738fc22cb53b5d84c135d4"}, + {file = "protobuf-3.20.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:74480f79a023f90dc6e18febbf7b8bac7508420f2006fabd512013c0c238f454"}, + {file = "protobuf-3.20.3-cp37-cp37m-win32.whl", hash = "sha256:b6cc7ba72a8850621bfec987cb72623e703b7fe2b9127a161ce61e61558ad905"}, + {file = "protobuf-3.20.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8c0c984a1b8fef4086329ff8dd19ac77576b384079247c770f29cc8ce3afa06c"}, + {file = "protobuf-3.20.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:de78575669dddf6099a8a0f46a27e82a1783c557ccc38ee620ed8cc96d3be7d7"}, + {file = "protobuf-3.20.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:f4c42102bc82a51108e449cbb32b19b180022941c727bac0cfd50170341f16ee"}, + {file = "protobuf-3.20.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:44246bab5dd4b7fbd3c0c80b6f16686808fab0e4aca819ade6e8d294a29c7050"}, + {file = "protobuf-3.20.3-cp38-cp38-win32.whl", hash = "sha256:c02ce36ec760252242a33967d51c289fd0e1c0e6e5cc9397e2279177716add86"}, + {file = "protobuf-3.20.3-cp38-cp38-win_amd64.whl", hash = "sha256:447d43819997825d4e71bf5769d869b968ce96848b6479397e29fc24c4a5dfe9"}, + {file = "protobuf-3.20.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:398a9e0c3eaceb34ec1aee71894ca3299605fa8e761544934378bbc6c97de23b"}, + {file = "protobuf-3.20.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf01b5720be110540be4286e791db73f84a2b721072a3711efff6c324cdf074b"}, + {file = "protobuf-3.20.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:daa564862dd0d39c00f8086f88700fdbe8bc717e993a21e90711acfed02f2402"}, + {file = "protobuf-3.20.3-cp39-cp39-win32.whl", hash = "sha256:819559cafa1a373b7096a482b504ae8a857c89593cf3a25af743ac9ecbd23480"}, + {file = "protobuf-3.20.3-cp39-cp39-win_amd64.whl", hash = "sha256:03038ac1cfbc41aa21f6afcbcd357281d7521b4157926f30ebecc8d4ea59dcb7"}, + {file = "protobuf-3.20.3-py2.py3-none-any.whl", hash = "sha256:a7ca6d488aa8ff7f329d4c545b2dbad8ac31464f1d8b1c87ad1346717731e4db"}, + {file = "protobuf-3.20.3.tar.gz", hash = "sha256:2e3427429c9cffebf259491be0af70189607f365c2f41c7c3764af6f337105f2"}, +] + [[package]] name = "pygments" version = "2.16.1" @@ -462,6 +702,46 @@ files = [ [package.extras] plugins = ["importlib-metadata"] +[[package]] +name = "pytest" +version = "7.4.3" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + [[package]] name = "pyyaml" version = "6.0.1" @@ -542,6 +822,17 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + [[package]] name = "snowballstemmer" version = "2.2.0" @@ -720,6 +1011,17 @@ Sphinx = ">=5" lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + [[package]] name = "uc-micro-py" version = "1.0.2" @@ -769,4 +1071,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 3.11" -content-hash = "8fe91bb06d76f41b5c50719a8374a8efda1232b1c7d04585807ed226106640d7" +content-hash = "120f01d7fd8f17f2842c07f85587821f07a0aafdda13efdf91393253b69b0cae" diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index d2f404cf..447218bf 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -9,11 +9,26 @@ readme = "README.md" [tool.poetry.dependencies] python = ">= 3.9, < 3.11" attrs = "^21.0" +ml-metadata = "^1.14.0" [tool.poetry.group.dev.dependencies] sphinx = "^7.2.6" furo = "^2023.9.10" myst-parser = { extras = ["linkify"], version = "^2.0.0" } +pytest = "^7.4.2" +coverage = { extras = ["toml"], version = "^7.3.2" } +pytest-cov = "^4.1.0" + +[tool.coverage.run] +branch = true +source = ["model_registry"] + +[tool.coverage.paths] +source = ["src", "*/site-packages"] +tests = ["tests", "*/tests"] + +[tool.coverage.report] +show_missing = true [build-system] requires = ["poetry-core"] diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index c2296036..2d60180b 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -10,10 +10,13 @@ * Move part of the description to API Reference docs (#120). """ +from __future__ import annotations + from enum import Enum, unique from typing import Optional from attrs import define, field +from ml_metadata.proto import Artifact from .base import ProtoBase @@ -22,13 +25,13 @@ class ArtifactState(Enum): """State of an artifact.""" - UNKNOWN = 0 - PENDING = 1 - LIVE = 2 - MARKED_FOR_DELETION = 3 - DELETED = 4 - ABANDONED = 5 - REFERENCE = 6 + UNKNOWN = Artifact.UNKNOWN + PENDING = Artifact.PENDING + LIVE = Artifact.LIVE + MARKED_FOR_DELETION = Artifact.MARKED_FOR_DELETION + DELETED = Artifact.DELETED + ABANDONED = Artifact.ABANDONED + REFERENCE = Artifact.REFERENCE @define(slots=False) @@ -45,8 +48,28 @@ class BaseArtifact(ProtoBase): uri: str state: ArtifactState = field(init=False, default=ArtifactState.UNKNOWN) + @classmethod + def get_proto_type(cls) -> type[Artifact]: + return Artifact -@define(slots=False) + def map(self) -> Artifact: + mlmd_obj = super().map() + mlmd_obj.uri = self.uri + mlmd_obj.state = ArtifactState[self.state.name].value + return mlmd_obj + + @classmethod + def unmap(cls, mlmd_obj: Artifact) -> BaseArtifact: + py_obj = super().unmap(mlmd_obj) + assert isinstance( + py_obj, BaseArtifact + ), f"Expected BaseArtifact, got {type(py_obj)}" + py_obj.uri = mlmd_obj.uri + py_obj.state = ArtifactState(mlmd_obj.state) + return py_obj + + +@define(slots=False, auto_attribs=True) class ModelArtifact(BaseArtifact): """Represents a Model. @@ -70,3 +93,34 @@ class ModelArtifact(BaseArtifact): storage_key: Optional[str] = field(kw_only=True, default=None) storage_path: Optional[str] = field(kw_only=True, default=None) service_account_name: Optional[str] = field(kw_only=True, default=None) + + def map(self) -> Artifact: + mlmd_obj = super().map() + props = { + "modelFormatName": self.model_format_name, + "modelFormatVersion": self.model_format_version, + "runtime": self.runtime, + "storageKey": self.storage_key, + "storagePath": self.storage_path, + "serviceAccountName": self.service_account_name, + } + self._map_props(props, mlmd_obj.properties) + return mlmd_obj + + @classmethod + def unmap(cls, mlmd_obj: Artifact) -> ModelArtifact: + py_obj = super().unmap(mlmd_obj) + assert isinstance( + py_obj, ModelArtifact + ), f"Expected ModelArtifact, got {type(py_obj)}" + py_obj.model_format_name = mlmd_obj.properties["modelFormatName"].string_value + py_obj.model_format_version = mlmd_obj.properties[ + "modelFormatVersion" + ].string_value + py_obj.runtime = mlmd_obj.properties["runtime"].string_value + py_obj.storage_key = mlmd_obj.properties["storageKey"].string_value + py_obj.storage_path = mlmd_obj.properties["storagePath"].string_value + py_obj.service_account_name = mlmd_obj.properties[ + "serviceAccountName" + ].string_value + return py_obj diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index 80a4babb..a8937042 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -1,13 +1,46 @@ -"""Base type for protos""" +"""Base types for model registry.""" -from abc import ABC -from typing import Optional +from __future__ import annotations + +from abc import ABC, abstractmethod +from collections.abc import Mapping +from typing import Any, Optional, Union from attrs import define, field +from ml_metadata.proto import Artifact, Context + +ProtoType = Union[Artifact, Context] +ScalarType = Union[bool, int, float, str] + + +class Mappable(ABC): + """Interface for types that can be mapped to and from proto types.""" + + @abstractmethod + def map(self) -> ProtoType: + """Map to a proto object. + + Returns: + ProtoType: Proto object. + """ + pass + + @classmethod + @abstractmethod + def unmap(cls, mlmd_obj: ProtoType) -> Mappable: + """Map from a proto object. + + Args: + ProtoType: Proto object. + + Returns: + Mappable: Python object. + """ + pass @define(slots=False, init=False) -class ProtoBase(ABC): +class ProtoBase(Mappable, ABC): """Abstract base type for protos This is a type defining common functionality for all types representing Model Registry protos, @@ -24,7 +57,90 @@ class ProtoBase(ABC): name: str = field(init=False) id: Optional[str] = field(init=False, default=None) - description: str = field(kw_only=True) + description: Optional[str] = field(kw_only=True, default=None) external_id: Optional[str] = field(kw_only=True, default=None) create_time_since_epoch: Optional[int] = field(init=False, default=None) last_update_time_since_epoch: Optional[int] = field(init=False, default=None) + + @classmethod + @abstractmethod + def get_proto_type(cls) -> type[ProtoType]: + """Proto type associated with this class. + + Returns: + ProtoType: Proto type. + """ + pass + + @staticmethod + def _map_props( + py_props: Mapping[str, Optional[ScalarType]], mlmd_props: dict[str, Any] + ): + """Map properties from Python to proto. + + Args: + py_props (dict[str, ScalarType]): Python properties. + mlmd_props (dict[str, Any]): Proto properties, will be modified in place. + """ + for key, value in py_props.items(): + if value is None: + continue + # TODO: use pattern matching here (3.10) + if isinstance(value, bool): + mlmd_props[key].bool_value = value + elif isinstance(value, int): + mlmd_props[key].int_value = value + elif isinstance(value, float): + mlmd_props[key].double_value = value + elif isinstance(value, str): + mlmd_props[key].string_value = value + else: + raise Exception(f"Unsupported type: {type(value)}") + + def map(self) -> ProtoType: + mlmd_obj = (self.get_proto_type())() + mlmd_obj.name = self.name + if self.id: + mlmd_obj.id = int(self.id) + if self.external_id: + mlmd_obj.external_id = self.external_id + if self.description: + mlmd_obj.properties["description"].string_value = self.description + return mlmd_obj + + @staticmethod + def _unmap_props(mlmd_props: dict[str, Any]) -> dict[str, ScalarType]: + """Map properties from proto to Python. + + Args: + mlmd_props (dict[str, Any]): Proto properties. + + Returns: + dict[str, ScalarType]: Python properties. + """ + py_props: dict[str, ScalarType] = {} + for key, value in mlmd_props.items(): + # TODO: use pattern matching here (3.10) + if value.HasField("bool_value"): + py_props[key] = value.bool_value + elif value.HasField("int_value"): + py_props[key] = value.int_value + elif value.HasField("double_value"): + py_props[key] = value.double_value + elif value.HasField("string_value"): + py_props[key] = value.string_value + else: + raise Exception(f"Unsupported type: {type(value)}") + + return py_props + + @classmethod + def unmap(cls, mlmd_obj: ProtoType) -> ProtoBase: + py_obj = cls.__new__(cls) + py_obj.id = str(mlmd_obj.id) + py_obj.name = mlmd_obj.name + py_obj.description = mlmd_obj.properties["description"].string_value + py_obj.external_id = mlmd_obj.external_id + py_obj.create_time_since_epoch = mlmd_obj.create_time_since_epoch + py_obj.last_update_time_since_epoch = mlmd_obj.last_update_time_since_epoch + return py_obj diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 46dffce4..355b3aef 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -9,22 +9,25 @@ * Move part of the description to API Reference docs (#120). """ -from abc import ABC -from typing import Union +from __future__ import annotations -from .artifacts import BaseArtifact, ModelArtifact -from .base import ProtoBase +from abc import ABC from attrs import define, field +from ml_metadata.proto import Context - -ScalarType = Union[str, int, float, bool] +from .artifacts import BaseArtifact, ModelArtifact +from .base import ProtoBase, ScalarType @define(slots=False, init=False) class BaseContext(ProtoBase, ABC): """Abstract base class for all contexts.""" + @classmethod + def get_proto_type(cls) -> type[Context]: + return Context + @define(slots=False) class ModelVersion(BaseContext): @@ -51,6 +54,31 @@ class ModelVersion(BaseContext): def __attrs_post_init__(self) -> None: self.name = self.version + def map(self) -> Context: + mlmd_obj = super().map() + # this should match the name of the registered model + mlmd_obj.properties["model_name"].string_value = self.model.name + mlmd_obj.properties["author"].string_value = self.author + if self.tags: + mlmd_obj.properties["tags"].string_value = ",".join(self.tags) + self._map_props(self.metadata, mlmd_obj.custom_properties) + return mlmd_obj + + @classmethod + def unmap(cls, mlmd_obj: Context) -> ModelVersion: + py_obj = super().unmap(mlmd_obj) + assert isinstance( + py_obj, ModelVersion + ), f"Expected ModelVersion, got {type(py_obj)}" + py_obj.version = py_obj.name + py_obj.author = mlmd_obj.properties["author"].string_value + tags = mlmd_obj.properties["tags"].string_value + if tags: + tags = tags.split(",") + py_obj.tags = tags or [] + py_obj.metadata = cls._unmap_props(mlmd_obj.custom_properties) + return py_obj + @define(slots=False) class RegisteredModel(BaseContext): diff --git a/clients/python/tests/__init__.py b/clients/python/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/python/tests/types/__init__.py b/clients/python/tests/types/__init__.py new file mode 100644 index 00000000..d42ec313 --- /dev/null +++ b/clients/python/tests/types/__init__.py @@ -0,0 +1,7 @@ +"""Tests for model registry types +""" + +from collections import namedtuple + + +Mapped = namedtuple("Mapped", ["proto", "py"]) diff --git a/clients/python/tests/types/test_artifact_mapping.py b/clients/python/tests/types/test_artifact_mapping.py new file mode 100644 index 00000000..de11219c --- /dev/null +++ b/clients/python/tests/types/test_artifact_mapping.py @@ -0,0 +1,95 @@ +"""Tests for artifact type mapping + +TODO: + * should we parametrize the tests? +""" + +from ml_metadata.proto import Artifact +from model_registry.types import ModelArtifact +from pytest import fixture + +from . import Mapped + + +@fixture +def complete_model() -> Mapped: + proto_model = Artifact() + proto_model.name = "test_model" + proto_model.external_id = "test_external_id" + proto_model.state = Artifact.UNKNOWN + proto_model.uri = "test_uri" + proto_model.properties["description"].string_value = "test description" + proto_model.properties["modelFormatName"].string_value = "test_format" + proto_model.properties["modelFormatVersion"].string_value = "test_format_version" + proto_model.properties["runtime"].string_value = "test_runtime" + proto_model.properties["storageKey"].string_value = "test_storage_key" + proto_model.properties["storagePath"].string_value = "test_storage_path" + proto_model.properties["serviceAccountName"].string_value = "test_account_name" + + py_model = ModelArtifact( + "test_model", + "test_uri", + description="test description", + external_id="test_external_id", + model_format_name="test_format", + model_format_version="test_format_version", + runtime="test_runtime", + storage_key="test_storage_key", + storage_path="test_storage_path", + service_account_name="test_account_name", + ) + + return Mapped(proto_model, py_model) + + +@fixture +def minimal_model() -> Mapped: + proto_model = Artifact() + proto_model.name = "test_model" + proto_model.state = Artifact.UNKNOWN + proto_model.uri = "test_uri" + + py_model = ModelArtifact("test_model", "test_uri") + return Mapped(proto_model, py_model) + + +def test_partial_model_mapping(minimal_model: Mapped): + mapped_model = minimal_model.py.map() + proto_model = minimal_model.proto + assert mapped_model.name == proto_model.name + assert mapped_model.state == proto_model.state + assert mapped_model.uri == proto_model.uri + + +def test_full_model_mapping(complete_model: Mapped): + mapped_model = complete_model.py.map() + proto_model = complete_model.proto + assert mapped_model.name == proto_model.name + assert mapped_model.state == proto_model.state + assert mapped_model.uri == proto_model.uri + assert mapped_model.external_id == proto_model.external_id + assert mapped_model.properties == proto_model.properties + + +def test_partial_model_unmapping(minimal_model: Mapped): + unmapped_model = ModelArtifact.unmap(minimal_model.proto) + py_model = minimal_model.py + assert unmapped_model.name == py_model.name + assert unmapped_model.state == py_model.state + assert unmapped_model.uri == py_model.uri + + +def test_full_model_unmapping(complete_model: Mapped): + unmapped_model = ModelArtifact.unmap(complete_model.proto) + py_model = complete_model.py + assert unmapped_model.name == py_model.name + assert unmapped_model.state == py_model.state + assert unmapped_model.uri == py_model.uri + assert unmapped_model.external_id == py_model.external_id + assert unmapped_model.description == py_model.description + assert unmapped_model.model_format_name == py_model.model_format_name + assert unmapped_model.model_format_version == py_model.model_format_version + assert unmapped_model.runtime == py_model.runtime + assert unmapped_model.storage_key == py_model.storage_key + assert unmapped_model.storage_path == py_model.storage_path + assert unmapped_model.service_account_name == py_model.service_account_name diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py new file mode 100644 index 00000000..418dd502 --- /dev/null +++ b/clients/python/tests/types/test_context_mapping.py @@ -0,0 +1,92 @@ +"""Tests for context type mapping + +TODO: + * should we parametrize the tests? +""" + +from pytest import fixture +from ml_metadata.proto import Context + +from model_registry.types import ModelArtifact, ModelVersion + +from . import Mapped + + +@fixture +def full_model_version() -> Mapped: + proto_version = Context() + proto_version.name = "1.0.0" + proto_version.external_id = "test_external_id" + proto_version.properties["description"].string_value = "test description" + proto_version.properties["model_name"].string_value = "test_model" + proto_version.properties["author"].string_value = "test_author" + proto_version.properties["tags"].string_value = "test_tag1,test_tag2" + proto_version.custom_properties["int_key"].int_value = 1 + proto_version.custom_properties["float_key"].double_value = 1.0 + proto_version.custom_properties["bool_key"].bool_value = True + proto_version.custom_properties["str_key"].string_value = "test_str" + + py_model = ModelArtifact("test_model", "test_uri") + py_version = ModelVersion( + py_model, + "1.0.0", + "test_author", + external_id="test_external_id", + description="test description", + ) + py_version.tags = ["test_tag1", "test_tag2"] + py_version.metadata = { + "int_key": 1, + "float_key": 1.0, + "bool_key": True, + "str_key": "test_str", + } + return Mapped(proto_version, py_version) + + +@fixture +def minimal_model_version() -> Mapped: + proto_version = Context() + proto_version.name = "1.0.0" + proto_version.properties["model_name"].string_value = "test_model" + proto_version.properties["author"].string_value = "test_author" + + py_model = ModelArtifact("test_model", "test_uri") + py_version = ModelVersion(py_model, "1.0.0", "test_author") + return Mapped(proto_version, py_version) + + +def test_partial_model_version_mapping(minimal_model_version: Mapped): + mapped_version = minimal_model_version.py.map() + proto_version = minimal_model_version.proto + assert mapped_version.name == proto_version.name + assert mapped_version.properties == proto_version.properties + + +def test_full_model_version_mapping(full_model_version: Mapped): + mapped_version = full_model_version.py.map() + proto_version = full_model_version.proto + assert mapped_version.name == proto_version.name + assert mapped_version.external_id == proto_version.external_id + assert mapped_version.properties == proto_version.properties + assert mapped_version.custom_properties == proto_version.custom_properties + + +def test_full_model_version_unmapping(full_model_version: Mapped): + unmapped_version = ModelVersion.unmap(full_model_version.proto) + py_version = full_model_version.py + assert unmapped_version.version == py_version.version + assert unmapped_version.description == py_version.description + assert unmapped_version.external_id == py_version.external_id + assert unmapped_version.author == py_version.author + assert unmapped_version.tags == py_version.tags + assert unmapped_version.metadata == py_version.metadata + + +def test_partial_model_version_unmapping(minimal_model_version: Mapped): + unmapped_version = ModelVersion.unmap(minimal_model_version.proto) + py_version = minimal_model_version.py + assert unmapped_version.version == py_version.version + assert unmapped_version.author == py_version.author + assert unmapped_version.tags == py_version.tags + assert unmapped_version.metadata == py_version.metadata From c968d5f5f530d96ba8fa2b4568fe26cb1617f1b3 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:23 -0300 Subject: [PATCH 104/254] py: add MetadataStore wrapper This simplifies the direct interface to gRPC provided by MLMD library for the client we want to expose: - we're usually dealing with single instances of proto types - in step with the Go client Signed-off-by: Isabella Basso do Amaral --- clients/python/docs/reference.md | 6 + .../python/src/model_registry/exceptions.py | 22 ++ .../src/model_registry/store/__init__.py | 10 + .../python/src/model_registry/store/base.py | 12 + .../src/model_registry/store/wrapper.py | 222 ++++++++++++++++++ .../python/src/model_registry/types/base.py | 6 +- .../src/model_registry/types/contexts.py | 4 +- clients/python/tests/store/__init__.py | 1 + clients/python/tests/store/test_wrapper.py | 120 ++++++++++ 9 files changed, 398 insertions(+), 5 deletions(-) create mode 100644 clients/python/src/model_registry/exceptions.py create mode 100644 clients/python/src/model_registry/store/__init__.py create mode 100644 clients/python/src/model_registry/store/base.py create mode 100644 clients/python/src/model_registry/store/wrapper.py create mode 100644 clients/python/tests/store/__init__.py create mode 100644 clients/python/tests/store/test_wrapper.py diff --git a/clients/python/docs/reference.md b/clients/python/docs/reference.md index d141fe30..05d3042d 100644 --- a/clients/python/docs/reference.md +++ b/clients/python/docs/reference.md @@ -5,3 +5,9 @@ ```{eval-rst} .. automodule:: model_registry.types ``` + +## Exceptions + +```{eval-rst} +.. automodule:: model_registry.exceptions +``` diff --git a/clients/python/src/model_registry/exceptions.py b/clients/python/src/model_registry/exceptions.py new file mode 100644 index 00000000..a5b6c8e6 --- /dev/null +++ b/clients/python/src/model_registry/exceptions.py @@ -0,0 +1,22 @@ +"""Exceptions for the model registry. +""" + + +class StoreException(Exception): + """Storage related error.""" + + +class UnsupportedTypeException(StoreException): + """Raised when an unsupported type is encountered.""" + + +class TypeNotFoundException(StoreException): + """Raised when a type cannot be found.""" + + +class ServerException(StoreException): + """Raised when the server returns a bad response.""" + + +class DuplicateException(StoreException): + """Raised when the user tries to put an object with a conflicting property.""" diff --git a/clients/python/src/model_registry/store/__init__.py b/clients/python/src/model_registry/store/__init__.py new file mode 100644 index 00000000..147af466 --- /dev/null +++ b/clients/python/src/model_registry/store/__init__.py @@ -0,0 +1,10 @@ +"""Model registry storage backends. +""" + +from .base import ProtoType, ScalarType +from .wrapper import MLMDStore + +__all__ = [ + "ProtoType", "ScalarType", + "MLMDStore", +] diff --git a/clients/python/src/model_registry/store/base.py b/clients/python/src/model_registry/store/base.py new file mode 100644 index 00000000..8b5c9b8c --- /dev/null +++ b/clients/python/src/model_registry/store/base.py @@ -0,0 +1,12 @@ +from typing import Union + +from ml_metadata.proto import Artifact, Context + + +ProtoType = Union[Artifact, Context] +"""Union of all proto types. """ +ScalarType = Union[str, int, float, bool] +"""Union of all scalar types. + +Those types are easy to map to and from proto types, and can also be queried in MLMD. +""" diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py new file mode 100644 index 00000000..f1137724 --- /dev/null +++ b/clients/python/src/model_registry/store/wrapper.py @@ -0,0 +1,222 @@ +from collections.abc import Sequence + +from ml_metadata import MetadataStore, errors +from ml_metadata.proto import ( + Artifact, + Attribution, + Context, + MetadataStoreClientConfig, + ParentContext, +) + +from .base import ProtoType +from model_registry.exceptions import ( + DuplicateException, + ServerException, + StoreException, + TypeNotFoundException, + UnsupportedTypeException, +) + + +class MLMDStore: + """MLMD storage backend.""" + + # cache for MLMD type IDs + _type_ids: dict[str, int] = {} + + def __init__(self, config: MetadataStoreClientConfig): + """Constructor. + + Args: + config (MetadataStoreClientConfig): MLMD config. + """ + self._mlmd_store = MetadataStore(config) + + def get_type_id(self, mlmd_pt: ProtoType, type_name: str) -> int: + """Get backend ID for a type. + + Args: + mlmd_pt (ProtoType): Proto type. + type_name (str): Name of the type. + + Returns: + int: Backend ID. + + Raises: + TypeNotFoundException: If the type doesn't exist. + ServerException: If there was an error getting the type. + UnsupportedTypeException: If the type is not supported. + """ + if type_name in self._type_ids: + return self._type_ids[type_name] + + if isinstance(mlmd_pt, Artifact): + mlmd_pt_name = "artifact" + get_type = self._mlmd_store.get_artifact_type + elif isinstance(mlmd_pt, Context): + mlmd_pt_name = "context" + get_type = self._mlmd_store.get_context_type + else: + raise UnsupportedTypeException(f"Unsupported type: {mlmd_pt}") + + try: + _type = get_type(type_name) + except errors.NotFoundError as e: + raise TypeNotFoundException( + f"{mlmd_pt_name} type {type_name} does not exist" + ) from e + except errors.InternalError as e: + raise ServerException( + f"Couldn't get {mlmd_pt_name} type {type_name} from MLMD store" + ) from e + + self._type_ids[type_name] = _type.id + + return _type.id + + def put_artifact(self, artifact: Artifact) -> int: + """Put an artifact in the store. + + Args: + artifact (Artifact): Artifact to put. + + Returns: + int: ID of the artifact. + + Raises: + DuplicateException: If an artifact with the same name or external id already exists. + TypeNotFoundException: If the type doesn't exist. + StoreException: If the artifact isn't properly formed. + """ + try: + return self._mlmd_store.put_artifacts([artifact])[0] + except errors.AlreadyExistsError as e: + raise DuplicateException(f"Artifact {artifact.name} already exists") from e + except errors.InvalidArgumentError as e: + raise StoreException("Artifact has invalid properties") from e + except errors.NotFoundError as e: + raise TypeNotFoundException( + f"Artifact type {artifact.type} does not exist" + ) from e + + def put_context(self, context: Context) -> int: + """Put a context in the store. + + Args: + context (Context): Context to put. + + Returns: + int: ID of the context. + + Raises: + DuplicateException: If a context with the same name or external id already exists. + TypeNotFoundException: If the type doesn't exist. + StoreException: If the context isn't propertly formed. + """ + try: + return self._mlmd_store.put_contexts([context])[0] + except errors.AlreadyExistsError as e: + raise DuplicateException(f"Context {context.name} already exists") from e + except errors.InvalidArgumentError as e: + raise StoreException("Context has invalid properties") from e + except errors.NotFoundError as e: + raise TypeNotFoundException( + f"Context type {context.type} does not exist" + ) from e + + def _filter_type( + self, type_name: str, protos: Sequence[ProtoType] + ) -> Sequence[ProtoType]: + return [proto for proto in protos if proto.type == type_name] + + def get_context(self, ctx_type_name: str, id: int) -> Context: + """Get a context from the store. + + Args: + ctx_type_name (str): Name of the context type. + id (int): ID of the context. + + Returns: + Context: Context. + + Raises: + StoreException: If the context doesn't exist. + """ + contexts = self._mlmd_store.get_contexts_by_id([id]) + + contexts = self._filter_type(ctx_type_name, contexts) + if contexts: + return contexts[0] + + raise StoreException(f"Context with ID {id} does not exist") + + def put_context_parent(self, parent_id: int, child_id: int): + """Put a parent-child relationship between two contexts. + + Args: + parent_id (int): ID of the parent context. + child_id (int): ID of the child context. + + Raises: + StoreException: If the parent context doesn't exist. + ServerException: If there was an error putting the parent context. + """ + try: + self._mlmd_store.put_parent_contexts( + [ParentContext(parent_id=parent_id, child_id=child_id)] + ) + except errors.AlreadyExistsError as e: + raise StoreException( + f"Parent context {parent_id} already exists for context {child_id}" + ) from e + except errors.InternalError as e: + raise ServerException( + f"Couldn't put parent context {parent_id} for context {child_id}" + ) from e + + def put_attribution(self, context_id: int, artifact_id: int): + """Put an attribution relationship between a context and an artifact. + + Args: + context_id (int): ID of the context. + artifact_id (int): ID of the artifact. + + Raises: + StoreException: Invalid argument. + """ + attribution = Attribution(context_id=context_id, artifact_id=artifact_id) + try: + self._mlmd_store.put_attributions_and_associations([attribution], []) + except errors.InvalidArgumentError as e: + if "artifact" in str(e).lower(): + raise StoreException( + f"Artifact with ID {artifact_id} does not exist" + ) from e + elif "context" in str(e).lower(): + raise StoreException( + f"Context with ID {context_id} does not exist" + ) from e + else: + raise StoreException(f"Invalid argument: {e}") from e + + def get_artifact(self, art_type_name: str, id: int) -> Artifact: + """Get an artifact from the store. + + Args: + art_type_name (str): Name of the artifact type. + id (int): ID of the artifact. + + Returns: + Artifact: Artifact. + + Raises: + StoreException: If the context doesn't exist. + """ + artifacts = self._mlmd_store.get_artifacts_by_id([id]) + + artifacts = self._filter_type(art_type_name, artifacts) + if artifacts: + return artifacts[0] + + raise StoreException(f"Artifact with ID {id} does not exist") diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index a8937042..af337030 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -4,13 +4,11 @@ from abc import ABC, abstractmethod from collections.abc import Mapping -from typing import Any, Optional, Union +from typing import Any, Optional from attrs import define, field -from ml_metadata.proto import Artifact, Context -ProtoType = Union[Artifact, Context] -ScalarType = Union[bool, int, float, str] +from model_registry.store import ProtoType, ScalarType class Mappable(ABC): diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 355b3aef..9252c7d6 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -16,8 +16,10 @@ from attrs import define, field from ml_metadata.proto import Context +from model_registry.store import ScalarType + from .artifacts import BaseArtifact, ModelArtifact -from .base import ProtoBase, ScalarType +from .base import ProtoBase @define(slots=False, init=False) diff --git a/clients/python/tests/store/__init__.py b/clients/python/tests/store/__init__.py new file mode 100644 index 00000000..ec9239a7 --- /dev/null +++ b/clients/python/tests/store/__init__.py @@ -0,0 +1 @@ +"""Tests for the store module.""" diff --git a/clients/python/tests/store/test_wrapper.py b/clients/python/tests/store/test_wrapper.py new file mode 100644 index 00000000..9c1f319a --- /dev/null +++ b/clients/python/tests/store/test_wrapper.py @@ -0,0 +1,120 @@ +"""Tests behavior of the MLMD wrapper. + +Tests whether the wrapper is properly handling misuses of the MLMD store, as common use cases +are already covered by the Registry client. +""" + +from ml_metadata.proto import ( + Artifact, + ArtifactType, + ConnectionConfig, + Context, + ContextType, +) +from model_registry.exceptions import ( + DuplicateException, + StoreException, + TypeNotFoundException, +) +from model_registry.store import MLMDStore +from pytest import fixture, raises + + +@fixture +def store_wrapper() -> MLMDStore: + config = ConnectionConfig() + config.fake_database.SetInParent() + return MLMDStore(config) + + +@fixture +def artifact(store_wrapper: MLMDStore) -> Artifact: + art_type = ArtifactType() + art_type.name = "test_artifact" + + art = Artifact() + art.name = "test_artifact" + art.type_id = store_wrapper._mlmd_store.put_artifact_type(art_type) + + return art + + +@fixture +def context(store_wrapper: MLMDStore) -> Context: + ctx_type = ContextType() + ctx_type.name = "test_context" + + ctx = Context() + ctx.name = "test_context" + ctx.type_id = store_wrapper._mlmd_store.put_context_type(ctx_type) + + return ctx + + +def test_get_undefined_artifact_type_id(store_wrapper: MLMDStore): + with raises(TypeNotFoundException): + store_wrapper.get_type_id(Artifact(), "undefined") + + +def test_get_undefined_context_type_id(store_wrapper: MLMDStore): + with raises(TypeNotFoundException): + store_wrapper.get_type_id(Context(), "undefined") + + +def test_put_invalid_artifact(store_wrapper: MLMDStore, artifact: Artifact): + artifact.properties["null"].int_value = 0 + + with raises(StoreException): + store_wrapper.put_artifact(artifact) + + +def test_put_duplicate_artifact(store_wrapper: MLMDStore, artifact: Artifact): + store_wrapper._mlmd_store.put_artifacts([artifact]) + with raises(DuplicateException): + store_wrapper.put_artifact(artifact) + + +def test_put_invalid_context(store_wrapper: MLMDStore, context: Context): + context.properties["null"].int_value = 0 + + with raises(StoreException): + store_wrapper.put_context(context) + + +def test_put_duplicate_context(store_wrapper: MLMDStore, context: Context): + store_wrapper._mlmd_store.put_contexts([context]) + + with raises(DuplicateException): + store_wrapper.put_context(context) + + +def test_put_attribution_with_invalid_context( + store_wrapper: MLMDStore, artifact: Artifact +): + art_id = store_wrapper._mlmd_store.put_artifacts([artifact])[0] + + with raises(StoreException) as store_error: + store_wrapper.put_attribution(0, art_id) + + assert "context" in str(store_error.value).lower() + + +def test_put_attribution_with_invalid_artifact( + store_wrapper: MLMDStore, context: Context +): + ctx_id = store_wrapper._mlmd_store.put_contexts([context])[0] + + with raises(StoreException) as store_error: + store_wrapper.put_attribution(ctx_id, 0) + + assert "artifact" in str(store_error.value).lower() + + +def test_get_undefined_artifact_by_id(store_wrapper: MLMDStore): + with raises(StoreException): + store_wrapper.get_artifact("dup", 0) + + +def test_get_undefined_context_by_id(store_wrapper: MLMDStore): + with raises(StoreException): + store_wrapper.get_context("dup", 0) From f0f9f122198c10d901f79a71e72e5eaf502ba7e2 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:23 -0300 Subject: [PATCH 105/254] py: add basic model registry functionality This sets the ground for our public interface, and should the client's "low-level" interface to the registry. Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 26 ++ clients/python/docs/reference.md | 6 + clients/python/src/model_registry/__init__.py | 4 + clients/python/src/model_registry/client.py | 222 ++++++++++++++++++ .../python/src/model_registry/types/base.py | 32 ++- clients/python/tests/conftest.py | 10 + clients/python/tests/store/test_wrapper.py | 8 - clients/python/tests/test_client.py | 160 +++++++++++++ 8 files changed, 459 insertions(+), 9 deletions(-) create mode 100644 clients/python/src/model_registry/client.py create mode 100644 clients/python/tests/conftest.py create mode 100644 clients/python/tests/test_client.py diff --git a/clients/python/README.md b/clients/python/README.md index 75f21091..f3d2b61c 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -25,6 +25,32 @@ version = ModelVersion(trained_model, "v1.0", "model author") model = RegisteredModel("my_model_name") ``` + +To register those objects, you can use the [`model_registry.ModelRegistry` class](src/model_registry/registry/client.py): + +```py +from model_registry import ModelRegistry + +registry = ModelRegistry("server-address", "port") + +model_id = registry.upsert_registered_model(model) + +# we need a model to associate the version to +version_id = registry.upsert_model_version(version, model_id) + +# we need a version to associate an trained model to +experiment_id = registry.upsert_model_artifact(trained_model, version_id) +``` + +To get previously registered objects from the registry, use +```py +another_model = registry.get_registered_model_by_id("another-model-id") + +another_version = registry.get_model_version_by_id("another-version-id", another_model.id) + +another_experiment = registry.get_model_artifact_by_id("another-model-artifact-id") +``` + ## Development Common tasks, such as building documentation and running tests, can be executed using [`nox`](https://github.com/wntrblm/nox) sessions. diff --git a/clients/python/docs/reference.md b/clients/python/docs/reference.md index 05d3042d..9e39ca75 100644 --- a/clients/python/docs/reference.md +++ b/clients/python/docs/reference.md @@ -1,5 +1,11 @@ # API Reference +## Client + +```{eval-rst} +.. automodule:: model_registry.client +``` + ## Types ```{eval-rst} diff --git a/clients/python/src/model_registry/__init__.py b/clients/python/src/model_registry/__init__.py index 85f20d12..cf2429c4 100644 --- a/clients/python/src/model_registry/__init__.py +++ b/clients/python/src/model_registry/__init__.py @@ -1,3 +1,7 @@ """Main package for the ODH model registry.""" __version__ = "0.0.0" + +from .client import ModelRegistry + +__all__ = ["ModelRegistry"] diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py new file mode 100644 index 00000000..5b5b852b --- /dev/null +++ b/clients/python/src/model_registry/client.py @@ -0,0 +1,222 @@ +"""Client for the model registry. +""" +from typing import Optional + +from ml_metadata.proto import Artifact, Context, MetadataStoreClientConfig + +from .exceptions import StoreException +from .store import ProtoType, MLMDStore +from .types import ModelArtifact, ModelVersion, RegisteredModel +from .types.artifacts import BaseArtifact +from .types.base import Mappable +from .types.contexts import BaseContext + + +class ModelRegistry: + """Model registry client.""" + + def __init__( + self, + server_address: str, + port: int, + client_key: Optional[str] = None, + server_cert: Optional[str] = None, + custom_ca: Optional[str] = None, + ): + """Constructor. + + Args: + server_address (str): Server address. + port (int): Server port. + client_key (str, optional): The PEM-encoded private key as a byte string. + server_cert (str, optional): The PEM-encoded certificate as a byte string. + custom_ca (str, optional): The PEM-encoded root certificates as a byte string. + """ + config = MetadataStoreClientConfig() + config.host = server_address + config.port = port + if client_key is not None: + config.ssl_config.client_key = client_key + if server_cert is not None: + config.ssl_config.server_cert = server_cert + if custom_ca is not None: + config.ssl_config.custom_ca = custom_ca + self._store = MLMDStore(config) + + def _map(self, py_obj: Mappable) -> ProtoType: + """Map a Python object to a proto object. + + Helper around the `map` method of the Python object. + + Args: + py_obj (Mappable): Python object. + + Returns: + ProtoType: Proto object. + """ + proto_obj = py_obj.map() + proto_obj.type_id = self._store.get_type_id( + proto_obj, py_obj.get_proto_type_name() + ) + return proto_obj + + def _unmap(self, proto_obj: ProtoType) -> Mappable: + """Map a proto object to a Python object. + + Helper around the `unmap` method, fetches the correct Python type to use. + + Args: + proto_obj (ProtoType): Proto object. + + Returns: + Mappable: Python object. + """ + type_name = proto_obj.type + try: + if isinstance(proto_obj, Artifact): + py_type = BaseArtifact.get_subclass(type_name) + elif isinstance(proto_obj, Context): + py_type = BaseContext.get_subclass(type_name) + else: + raise StoreException(f"Unknown proto type: {type_name}") + except Exception: + raise + return py_type.unmap(proto_obj) + + def upsert_registered_model(self, registered_model: RegisteredModel) -> str: + """Upsert a registered model. + + Updates or creates a registered model on the server. + This updates the registered_model instance passed in with new data from the servers. + + Args: + registered_model (RegisteredModel): Registered model. + + Returns: + str: ID of the registered model. + """ + proto_obj = self._map(registered_model) + id = self._store.put_context(proto_obj) + new_py_rm = self._unmap( + self._store.get_context(RegisteredModel.get_proto_type_name(), id) + ) + id = str(id) + assert isinstance(new_py_rm, RegisteredModel), "Expected a registered model" + registered_model.id = id + registered_model.create_time_since_epoch = new_py_rm.create_time_since_epoch + registered_model.last_update_time_since_epoch = ( + new_py_rm.last_update_time_since_epoch + ) + return id + + def get_registered_model_by_id(self, id: str) -> RegisteredModel: + """Fetch a registered model by its ID. + + Args: + id (str): Registered model ID. + + Returns: + RegisteredModel: Registered model. + """ + proto_rm = self._store.get_context( + RegisteredModel.get_proto_type_name(), id=int(id) + ) + py_rm = self._unmap(proto_rm) + assert isinstance(py_rm, RegisteredModel), "Expected a registered model" + # TODO: reinsert versions + return py_rm + + def upsert_model_version( + self, model_version: ModelVersion, registered_model_id: str + ) -> str: + """Upsert a model version. + + Updates or creates a model version on the server. + This updates the model_version instance passed in with new data from the servers. + + Args: + model_version (ModelVersion): Model version to upsert. + registered_model_id (str): ID of the registered model this version will be associated to. + + Returns: + str: ID of the model version. + """ + rm_id = int(registered_model_id) + proto_mv = self._map(model_version) + id = self._store.put_context(proto_mv) + self._store.put_context_parent(rm_id, id) + new_py_mv = self._unmap( + self._store.get_context(ModelVersion.get_proto_type_name(), id) + ) + assert isinstance(new_py_mv, ModelVersion), "Expected a model version" + id = str(id) + model_version.id = id + model_version.create_time_since_epoch = new_py_mv.create_time_since_epoch + model_version.last_update_time_since_epoch = ( + new_py_mv.last_update_time_since_epoch + ) + return id + + def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: + """Fetch a model version by its ID. + + Args: + model_version_id (str): Model version ID. + + Returns: + ModelVersion: Model version. + """ + proto_mv = self._store.get_context( + ModelVersion.get_proto_type_name(), id=int(model_version_id) + ) + py_mv = self._unmap(proto_mv) + assert isinstance(py_mv, ModelVersion), "Expected a model version" + # TODO: reinsert model + return py_mv + + def upsert_model_artifact( + self, model_artifact: ModelArtifact, model_version_id: str + ) -> None: + """Upsert a model artifact. + + Updates or creates a model artifact on the server. + This updates the model_artifact instance passed in with new data from the servers. + + Args: + model_artifact (ModelArtifact): Model artifact to upsert. + model_version_id (str): ID of the model version this artifact will be associated to. + + Returns: + str: ID of the model artifact. + """ + # TODO: check if mv doesn't have ma already + mv_id = int(model_version_id) + proto_ma = self._map(model_artifact) + id = self._store.put_artifact(proto_ma) + self._store.put_attribution(mv_id, id) + new_py_ma = self._unmap( + self._store.get_artifact(ModelArtifact.get_proto_type_name(), id) + ) + id = str(id) + model_artifact.id = id + model_artifact.create_time_since_epoch = new_py_ma.create_time_since_epoch + model_artifact.last_update_time_since_epoch = ( + new_py_ma.last_update_time_since_epoch + ) + return id + + def get_model_artifact_by_id(self, id: str) -> ModelArtifact: + """Fetch a model artifact by its ID. + + Args: + id (str): Model artifact ID. + + Returns: + ModelArtifact: Model artifact. + """ + proto_ma = self._store.get_artifact( + ModelArtifact.get_proto_type_name(), int(id) + ) + py_ma = self._unmap(proto_ma) + assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" + return py_ma diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index af337030..6eaea28f 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -4,7 +4,8 @@ from abc import ABC, abstractmethod from collections.abc import Mapping -from typing import Any, Optional +from inspect import isabstract +from typing import Any, ClassVar, Optional from attrs import define, field @@ -14,6 +15,15 @@ class Mappable(ABC): """Interface for types that can be mapped to and from proto types.""" + @classmethod + def get_proto_type_name(cls) -> str: + """Name of the proto type + + Returns: + str: Name of the class prefixed with `odh.` + """ + return f"odh.{cls.__name__}" + @abstractmethod def map(self) -> ProtoType: """Map to a proto object. @@ -60,6 +70,26 @@ class ProtoBase(Mappable, ABC): create_time_since_epoch: Optional[int] = field(init=False, default=None) last_update_time_since_epoch: Optional[int] = field(init=False, default=None) + _types_map: ClassVar[dict[str, ProtoBase]] = {} + + def __init_subclass__(cls): + super().__init_subclass__() + if isabstract(cls): + return + cls._types_map[cls.get_proto_type_name()] = cls + + @classmethod + def get_subclass(cls, proto_type_name: str) -> Mappable: + """Get a subclass by proto type name. + + Args: + proto_type_name (str): Name of the proto type. + + Returns: + Mappable: Subclass. + """ + return cls._types_map[proto_type_name] + @classmethod @abstractmethod def get_proto_type(cls) -> type[ProtoType]: diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py new file mode 100644 index 00000000..81490b29 --- /dev/null +++ b/clients/python/tests/conftest.py @@ -0,0 +1,10 @@ +from ml_metadata.proto import ConnectionConfig +from model_registry.store.wrapper import MLMDStore +from pytest import fixture + + +@fixture +def store_wrapper() -> MLMDStore: + config = ConnectionConfig() + config.fake_database.SetInParent() + return MLMDStore(config) diff --git a/clients/python/tests/store/test_wrapper.py b/clients/python/tests/store/test_wrapper.py index 9c1f319a..82b52b8f 100644 --- a/clients/python/tests/store/test_wrapper.py +++ b/clients/python/tests/store/test_wrapper.py @@ -7,7 +7,6 @@ from ml_metadata.proto import ( Artifact, ArtifactType, - ConnectionConfig, Context, ContextType, ) @@ -20,13 +19,6 @@ from pytest import fixture, raises -@fixture -def store_wrapper() -> MLMDStore: - config = ConnectionConfig() - config.fake_database.SetInParent() - return MLMDStore(config) - - @fixture def artifact(store_wrapper: MLMDStore) -> Artifact: art_type = ArtifactType() diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py new file mode 100644 index 00000000..6cdad8a6 --- /dev/null +++ b/clients/python/tests/test_client.py @@ -0,0 +1,160 @@ +"""Tests for user facing model registry APIs.""" + +from collections import namedtuple + +from ml_metadata.proto import ( + ArtifactType, + Artifact, + ContextType, + Context, + metadata_store_pb2, +) +from model_registry import ModelRegistry +from model_registry.store import MLMDStore +from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel +from pytest import fixture + + +@fixture +def model_registry(store_wrapper: MLMDStore) -> ModelRegistry: + mr = object.__new__(ModelRegistry) + mr._store = store_wrapper + return mr + + +Mapped = namedtuple("Mapped", ["proto", "py"]) + + +@fixture +def model(store_wrapper: MLMDStore) -> Mapped: + art_type = ArtifactType() + art_type.name = ModelArtifact.get_proto_type_name() + props = [ + "description", + "modelFormatName", + "modelFormatVersion", + "runtime", + "storageKey", + "storagePath", + "serviceAccountName", + ] + for key in props: + art_type.properties[key] = metadata_store_pb2.STRING + + art = Artifact() + art.name = "model" + art.type_id = store_wrapper._mlmd_store.put_artifact_type(art_type) + art.uri = "uri" + + return Mapped(art, ModelArtifact("model", "uri")) + + +@fixture +def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: + ctx_type = ContextType() + ctx_type.name = ModelVersion.get_proto_type_name() + props = [ + "author", + "description", + "model_name", + "tags", + ] + for key in props: + ctx_type.properties[key] = metadata_store_pb2.STRING + + ctx = Context() + ctx.name = "version" + ctx.type_id = store_wrapper._mlmd_store.put_context_type(ctx_type) + ctx.properties["author"].string_value = "author" + ctx.properties["model_name"].string_value = model.py.name + + return Mapped(ctx, ModelVersion(model.py, "version", "author")) + + +@fixture +def registered_model(store_wrapper: MLMDStore, model: Mapped) -> Mapped: + ctx_type = ContextType() + ctx_type.name = RegisteredModel.get_proto_type_name() + ctx_type.properties["description"] = metadata_store_pb2.STRING + + ctx = Context() + ctx.name = model.py.name + ctx.type_id = store_wrapper._mlmd_store.put_context_type(ctx_type) + + return Mapped(ctx, RegisteredModel(model.py.name)) + + +# TODO: should we test insert/update separately? +def test_upsert_registered_model( + model_registry: ModelRegistry, registered_model: Mapped +): + model_registry.upsert_registered_model(registered_model.py) + + rm_proto = model_registry._store._mlmd_store.get_context_by_type_and_name( + RegisteredModel.get_proto_type_name(), registered_model.proto.name + ) + assert rm_proto is not None + assert registered_model.py.id == str(rm_proto.id) + assert registered_model.py.name == rm_proto.name + + +def test_get_registered_model_by_id( + model_registry: ModelRegistry, registered_model: Mapped +): + id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + id = str(id) + + mlmd_rm = model_registry.get_registered_model_by_id(id) + assert mlmd_rm.id == id + assert mlmd_rm.name == registered_model.proto.name + + +def test_upsert_model_version( + model_registry: ModelRegistry, model_version: Mapped, registered_model: Mapped +): + rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + rm_id = str(rm_id) + + model_registry.upsert_model_version(model_version.py, rm_id) + + mv_proto = model_registry._store._mlmd_store.get_context_by_type_and_name( + ModelVersion.get_proto_type_name(), model_version.proto.name + ) + assert mv_proto is not None + assert model_version.py.id == str(mv_proto.id) + assert model_version.py.version == mv_proto.name + + +def test_get_model_version_by_id(model_registry: ModelRegistry, model_version: Mapped): + id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + id = str(id) + + mlmd_mv = model_registry.get_model_version_by_id(id) + assert mlmd_mv.id == id + assert mlmd_mv.version == model_version.proto.name + + +def test_upsert_model_artifact( + model_registry: ModelRegistry, model: Mapped, model_version: Mapped +): + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + mv_id = str(mv_id) + + model_registry.upsert_model_artifact(model.py, mv_id) + + ma_proto = model_registry._store._mlmd_store.get_artifact_by_type_and_name( + ModelArtifact.get_proto_type_name(), model.proto.name + ) + assert ma_proto is not None + assert model.py.id == str(ma_proto.id) + assert model.py.name == ma_proto.name + + +def test_get_model_artifact_by_id(model_registry: ModelRegistry, model: Mapped): + id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + id = str(id) + + mlmd_ma = model_registry.get_model_artifact_by_id(id) + + assert mlmd_ma.id == id + assert mlmd_ma.name == model.proto.name From d8e625a0e37fd8e21ea0a62f6d48f2defa06e0d8 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:24 -0300 Subject: [PATCH 106/254] py: add support for name prefixes Because of a limitation in the MLMD C++ server, names can't be repeated for the same types of artifacts, contexts, etc. so we need to prefix names to be able to allow the users to have more freedom when choosing them. Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 2 +- clients/python/src/model_registry/client.py | 2 + .../src/model_registry/types/artifacts.py | 9 +++- .../python/src/model_registry/types/base.py | 36 ++++++++++++++- .../src/model_registry/types/contexts.py | 12 ++++- clients/python/tests/registry/test_client.py | 0 clients/python/tests/test_client.py | 44 ++++++++++++++++--- .../tests/types/test_artifact_mapping.py | 18 ++++++-- .../tests/types/test_context_mapping.py | 8 ++-- 9 files changed, 110 insertions(+), 21 deletions(-) create mode 100644 clients/python/tests/registry/test_client.py diff --git a/clients/python/README.md b/clients/python/README.md index f3d2b61c..67a7f7b7 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -48,7 +48,7 @@ another_model = registry.get_registered_model_by_id("another-model-id") another_version = registry.get_model_version_by_id("another-version-id", another_model.id) -another_experiment = registry.get_model_artifact_by_id("another-model-artifact-id") +another_trained_model = registry.get_model_artifact_by_id("another-model-artifact-id") ``` ## Development diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 5b5b852b..2ff07cfd 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -142,6 +142,8 @@ def upsert_model_version( str: ID of the model version. """ rm_id = int(registered_model_id) + # this is not ideal but we need this info for the prefix + model_version._registered_model_id = rm_id proto_mv = self._map(model_version) id = self._store.put_context(proto_mv) self._store.put_context_parent(rm_id, id) diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index 2d60180b..11c5a097 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -14,11 +14,12 @@ from enum import Enum, unique from typing import Optional +from uuid import uuid4 from attrs import define, field from ml_metadata.proto import Artifact -from .base import ProtoBase +from .base import Prefixable, ProtoBase @unique @@ -70,7 +71,7 @@ def unmap(cls, mlmd_obj: Artifact) -> BaseArtifact: @define(slots=False, auto_attribs=True) -class ModelArtifact(BaseArtifact): +class ModelArtifact(BaseArtifact, Prefixable): """Represents a Model. Attributes: @@ -94,6 +95,10 @@ class ModelArtifact(BaseArtifact): storage_path: Optional[str] = field(kw_only=True, default=None) service_account_name: Optional[str] = field(kw_only=True, default=None) + @property + def mlmd_name_prefix(self) -> str: + return uuid4().hex + def map(self) -> Artifact: mlmd_obj = super().map() props = { diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index 6eaea28f..3392577a 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -24,6 +24,13 @@ def get_proto_type_name(cls) -> str: """ return f"odh.{cls.__name__}" + @property + @abstractmethod + def proto_name(self) -> str: + """Name of the proto object. + """ + pass + @abstractmethod def map(self) -> ProtoType: """Map to a proto object. @@ -47,6 +54,20 @@ def unmap(cls, mlmd_obj: ProtoType) -> Mappable: pass +class Prefixable(ABC): + """Interface for types that are prefixed. + + We use prefixes to ensure that the user can insert more than one instance of the same type + with the same name/external_id. + """ + @property + @abstractmethod + def mlmd_name_prefix(self) -> str: + """Prefix to be used in the proto object. + """ + pass + + @define(slots=False, init=False) class ProtoBase(Mappable, ABC): """Abstract base type for protos @@ -90,6 +111,12 @@ def get_subclass(cls, proto_type_name: str) -> Mappable: """ return cls._types_map[proto_type_name] + @property + def proto_name(self) -> str: + if isinstance(self, Prefixable): + return f"{self.mlmd_name_prefix}:{self.name}" + return self.name + @classmethod @abstractmethod def get_proto_type(cls) -> type[ProtoType]: @@ -127,7 +154,7 @@ def _map_props( def map(self) -> ProtoType: mlmd_obj = (self.get_proto_type())() - mlmd_obj.name = self.name + mlmd_obj.name = self.proto_name if self.id: mlmd_obj.id = int(self.id) if self.external_id: @@ -166,7 +193,12 @@ def _unmap_props(mlmd_props: dict[str, Any]) -> dict[str, ScalarType]: def unmap(cls, mlmd_obj: ProtoType) -> ProtoBase: py_obj = cls.__new__(cls) py_obj.id = str(mlmd_obj.id) - py_obj.name = mlmd_obj.name + if isinstance(py_obj, Prefixable): + name: str = mlmd_obj.name + assert ':' in name, f"Expected {name} to be prefixed" + py_obj.name = name.split(':', 1)[1] + else: + py_obj.name = mlmd_obj.name py_obj.description = mlmd_obj.properties["description"].string_value py_obj.external_id = mlmd_obj.external_id py_obj.create_time_since_epoch = mlmd_obj.create_time_since_epoch diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 9252c7d6..277c5b3f 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -12,6 +12,7 @@ from __future__ import annotations from abc import ABC +from typing import Optional from attrs import define, field from ml_metadata.proto import Context @@ -19,7 +20,7 @@ from model_registry.store import ScalarType from .artifacts import BaseArtifact, ModelArtifact -from .base import ProtoBase +from .base import Prefixable, ProtoBase @define(slots=False, init=False) @@ -32,7 +33,7 @@ def get_proto_type(cls) -> type[Context]: @define(slots=False) -class ModelVersion(BaseContext): +class ModelVersion(BaseContext, Prefixable): """Represents a model version. Attributes: @@ -53,9 +54,16 @@ class ModelVersion(BaseContext): tags: list[str] = field(init=False, factory=list) metadata: dict[str, ScalarType] = field(init=False, factory=dict) + _registered_model_id: Optional[int] = field(init=False, default=None) + def __attrs_post_init__(self) -> None: self.name = self.version + @property + def mlmd_name_prefix(self): + assert self._registered_model_id is not None, "There's no registered model associated with this version" + return self._registered_model_id + def map(self) -> Context: mlmd_obj = super().map() # this should match the name of the registered model diff --git a/clients/python/tests/registry/test_client.py b/clients/python/tests/registry/test_client.py new file mode 100644 index 00000000..e69de29b diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 6cdad8a6..89fb3918 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -2,6 +2,7 @@ from collections import namedtuple +from attrs import evolve from ml_metadata.proto import ( ArtifactType, Artifact, @@ -42,6 +43,7 @@ def model(store_wrapper: MLMDStore) -> Mapped: art_type.properties[key] = metadata_store_pb2.STRING art = Artifact() + # we can't test the name directly as it's prefixed art.name = "model" art.type_id = store_wrapper._mlmd_store.put_artifact_type(art_type) art.uri = "uri" @@ -63,6 +65,7 @@ def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: ctx_type.properties[key] = metadata_store_pb2.STRING ctx = Context() + # we can't test the name directly as it's prefixed ctx.name = "version" ctx.type_id = store_wrapper._mlmd_store.put_context_type(ctx_type) ctx.properties["author"].string_value = "author" @@ -106,6 +109,7 @@ def test_get_registered_model_by_id( mlmd_rm = model_registry.get_registered_model_by_id(id) assert mlmd_rm.id == id + assert mlmd_rm.name == registered_model.py.name assert mlmd_rm.name == registered_model.proto.name @@ -118,43 +122,69 @@ def test_upsert_model_version( model_registry.upsert_model_version(model_version.py, rm_id) mv_proto = model_registry._store._mlmd_store.get_context_by_type_and_name( - ModelVersion.get_proto_type_name(), model_version.proto.name + ModelVersion.get_proto_type_name(), f"{rm_id}:{model_version.proto.name}" ) assert mv_proto is not None assert model_version.py.id == str(mv_proto.id) - assert model_version.py.version == mv_proto.name + assert model_version.py.version != mv_proto.name def test_get_model_version_by_id(model_registry: ModelRegistry, model_version: Mapped): + model_version.proto.name = f"1:{model_version.proto.name}" + id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] id = str(id) mlmd_mv = model_registry.get_model_version_by_id(id) assert mlmd_mv.id == id - assert mlmd_mv.version == model_version.proto.name + assert mlmd_mv.name == model_version.py.name + assert mlmd_mv.version != model_version.proto.name def test_upsert_model_artifact( - model_registry: ModelRegistry, model: Mapped, model_version: Mapped + monkeypatch, model_registry: ModelRegistry, model: Mapped, model_version: Mapped ): + monkeypatch.setattr(ModelArtifact, "mlmd_name_prefix", "test_prefix") + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] mv_id = str(mv_id) model_registry.upsert_model_artifact(model.py, mv_id) ma_proto = model_registry._store._mlmd_store.get_artifact_by_type_and_name( - ModelArtifact.get_proto_type_name(), model.proto.name + ModelArtifact.get_proto_type_name(), f"test_prefix:{model.proto.name}" ) assert ma_proto is not None assert model.py.id == str(ma_proto.id) - assert model.py.name == ma_proto.name + assert model.py.name != ma_proto.name + + +def test_upsert_duplicate_model_artifact( + model_registry: ModelRegistry, model: Mapped, model_version: Mapped +): + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + mv_id = str(mv_id) + + ma1 = evolve(model.py) + model_registry.upsert_model_artifact(ma1, mv_id) + ma2 = evolve(model.py) + model_registry.upsert_model_artifact(ma2, mv_id) + + ma_protos = model_registry._store._mlmd_store.get_artifacts_by_id( + [int(ma1.id), int(ma2.id)] + ) + assert ma1.name == ma2.name + assert ma1.name != str(ma_protos[0].name) + assert ma2.name != str(ma_protos[1].name) def test_get_model_artifact_by_id(model_registry: ModelRegistry, model: Mapped): + model.proto.name = f"test_prefix:{model.proto.name}" id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] id = str(id) mlmd_ma = model_registry.get_model_artifact_by_id(id) assert mlmd_ma.id == id - assert mlmd_ma.name == model.proto.name + assert mlmd_ma.name == model.py.name + assert mlmd_ma.name != model.proto.name diff --git a/clients/python/tests/types/test_artifact_mapping.py b/clients/python/tests/types/test_artifact_mapping.py index de11219c..a249d411 100644 --- a/clients/python/tests/types/test_artifact_mapping.py +++ b/clients/python/tests/types/test_artifact_mapping.py @@ -14,7 +14,7 @@ @fixture def complete_model() -> Mapped: proto_model = Artifact() - proto_model.name = "test_model" + proto_model.name = "test_prefix:test_model" proto_model.external_id = "test_external_id" proto_model.state = Artifact.UNKNOWN proto_model.uri = "test_uri" @@ -45,7 +45,7 @@ def complete_model() -> Mapped: @fixture def minimal_model() -> Mapped: proto_model = Artifact() - proto_model.name = "test_model" + proto_model.name = "test_prefix:test_model" proto_model.state = Artifact.UNKNOWN proto_model.uri = "test_uri" @@ -53,7 +53,9 @@ def minimal_model() -> Mapped: return Mapped(proto_model, py_model) -def test_partial_model_mapping(minimal_model: Mapped): +def test_partial_model_mapping(monkeypatch, minimal_model: Mapped): + monkeypatch.setattr(ModelArtifact, "mlmd_name_prefix", "test_prefix") + mapped_model = minimal_model.py.map() proto_model = minimal_model.proto assert mapped_model.name == proto_model.name @@ -61,7 +63,9 @@ def test_partial_model_mapping(minimal_model: Mapped): assert mapped_model.uri == proto_model.uri -def test_full_model_mapping(complete_model: Mapped): +def test_full_model_mapping(monkeypatch, complete_model: Mapped): + monkeypatch.setattr(ModelArtifact, "mlmd_name_prefix", "test_prefix") + mapped_model = complete_model.py.map() proto_model = complete_model.proto assert mapped_model.name == proto_model.name @@ -93,3 +97,9 @@ def test_full_model_unmapping(complete_model: Mapped): assert unmapped_model.storage_key == py_model.storage_key assert unmapped_model.storage_path == py_model.storage_path assert unmapped_model.service_account_name == py_model.service_account_name + + +def test_model_prefix_generation(minimal_model: Mapped): + name1 = minimal_model.py.map().name + name2 = minimal_model.py.map().name + assert name1 != name2 diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index 418dd502..a491e1fd 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -7,7 +7,7 @@ from pytest import fixture from ml_metadata.proto import Context -from model_registry.types import ModelArtifact, ModelVersion +from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel from . import Mapped @@ -15,7 +15,7 @@ @fixture def full_model_version() -> Mapped: proto_version = Context() - proto_version.name = "1.0.0" + proto_version.name = "1:1.0.0" proto_version.external_id = "test_external_id" proto_version.properties["description"].string_value = "test description" proto_version.properties["model_name"].string_value = "test_model" @@ -34,6 +34,7 @@ def full_model_version() -> Mapped: external_id="test_external_id", description="test description", ) + py_version._registered_model_id = 1 py_version.tags = ["test_tag1", "test_tag2"] py_version.metadata = { "int_key": 1, @@ -47,12 +48,13 @@ def full_model_version() -> Mapped: @fixture def minimal_model_version() -> Mapped: proto_version = Context() - proto_version.name = "1.0.0" + proto_version.name = "1:1.0.0" proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" py_model = ModelArtifact("test_model", "test_uri") py_version = ModelVersion(py_model, "1.0.0", "test_author") + py_version._registered_model_id = 1 return Mapped(proto_version, py_version) From e1dbb8cc4603d3f874a0faf91cc9b9cfcdab570f Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:24 -0300 Subject: [PATCH 107/254] py: add params to artifact query Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 13 ++- clients/python/src/model_registry/client.py | 43 +++++++++- .../src/model_registry/store/wrapper.py | 29 ++++++- clients/python/tests/test_client.py | 83 +++++++++++++++++-- 4 files changed, 154 insertions(+), 14 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index 67a7f7b7..e2fcc3d6 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -18,7 +18,8 @@ Registry objects can be created by doing from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel trained_model = ModelArtifact("my_model_name", "resource_URI", - description="Model description") + description="Model description", + external_id="unique_reference") version = ModelVersion(trained_model, "v1.0", "model author") @@ -51,6 +52,16 @@ another_version = registry.get_model_version_by_id("another-version-id", another another_trained_model = registry.get_model_artifact_by_id("another-model-artifact-id") ``` +You can also perform queries by parameters to get model artifacts: + +```py +# we can get the model associated to a version +another_trained_model = registry.get_model_artifact_by_params(model_version_id=another_version.id) + +# or get it by a unique identifier +trained_model = registry.get_model_artifact_by_params(external_id="unique_reference") +``` + ## Development Common tasks, such as building documentation and running tests, can be executed using [`nox`](https://github.com/wntrblm/nox) sessions. diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 2ff07cfd..76b38cf8 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -173,7 +173,9 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: ) py_mv = self._unmap(proto_mv) assert isinstance(py_mv, ModelVersion), "Expected a model version" - # TODO: reinsert model + py_mv.model = self.get_model_artifact_by_params( + model_version_id=model_version_id + ) return py_mv def upsert_model_artifact( @@ -191,8 +193,17 @@ def upsert_model_artifact( Returns: str: ID of the model artifact. """ - # TODO: check if mv doesn't have ma already mv_id = int(model_version_id) + try: + self._store.get_attributed_artifact( + ModelArtifact.get_proto_type_name(), mv_id + ) + raise StoreException( + f"Model version with ID {mv_id} already has a model artifact" + ) + except StoreException as e: + if "found" not in str(e).lower(): + raise proto_ma = self._map(model_artifact) id = self._store.put_artifact(proto_ma) self._store.put_attribution(mv_id, id) @@ -222,3 +233,31 @@ def get_model_artifact_by_id(self, id: str) -> ModelArtifact: py_ma = self._unmap(proto_ma) assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" return py_ma + + def get_model_artifact_by_params( + self, model_version_id: Optional[str] = None, external_id: Optional[str] = None + ) -> ModelArtifact: + """Fetch a model artifact either by external ID or by the ID of its associated model version. + + Args: + model_version_id (str, optional): ID of the associated model version. + external_id (str, optional): Model artifact external ID. + + Returns: + ModelArtifact: Model artifact. + """ + if external_id: + proto_ma = self._store.get_artifact( + ModelArtifact.get_proto_type_name(), external_id=external_id + ) + elif not model_version_id: + raise StoreException( + "Either model_version_id or external_id must be provided" + ) + else: + proto_ma = self._store.get_attributed_artifact( + ModelArtifact.get_proto_type_name(), int(model_version_id) + ) + py_ma = self._unmap(proto_ma) + assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" + return py_ma diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index f1137724..f716f50f 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -1,4 +1,5 @@ from collections.abc import Sequence +from typing import Optional from ml_metadata import MetadataStore, errors from ml_metadata.proto import ( @@ -200,7 +201,13 @@ def put_attribution(self, context_id: int, artifact_id: int): else: raise StoreException(f"Invalid argument: {e}") from e - def get_artifact(self, art_type_name: str, id: int) -> Artifact: + def get_artifact( + self, + art_type_name: str, + id: Optional[int] = None, + name: Optional[str] = None, + external_id: Optional[str] = None, + ) -> Artifact: """Get an artifact from the store. Args: @@ -213,10 +220,28 @@ def get_artifact(self, art_type_name: str, id: int) -> Artifact: Raises: StoreException: If the context doesn't exist. """ - artifacts = self._mlmd_store.get_artifacts_by_id([id]) + if name is not None: + return self._mlmd_store.get_artifact_by_type_and_name(art_type_name, name) + + if id is not None: + artifacts = self._mlmd_store.get_artifacts_by_id([id]) + elif external_id is not None: + artifacts = self._mlmd_store.get_artifacts_by_external_ids([external_id]) + else: + raise StoreException("Either id, name or external_id must be provided") artifacts = self._filter_type(art_type_name, artifacts) if artifacts: return artifacts[0] raise StoreException(f"Artifact with ID {id} does not exist") + + def get_attributed_artifact(self, art_type_name: str, ctx_id: int) -> Artifact: + try: + artifacts = self._mlmd_store.get_artifacts_by_context(ctx_id) + except errors.InternalError as e: + raise ServerException(f"Couldn't get artifacts by context {ctx_id}") from e + artifacts = self._filter_type(art_type_name, artifacts) + if artifacts: + return artifacts[0] + raise StoreException("No artifacts found") diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 89fb3918..315fc7f7 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -6,14 +6,16 @@ from ml_metadata.proto import ( ArtifactType, Artifact, + Attribution, ContextType, Context, metadata_store_pb2, ) from model_registry import ModelRegistry +from model_registry.exceptions import StoreException from model_registry.store import MLMDStore from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel -from pytest import fixture +from pytest import fixture, raises @fixture @@ -129,12 +131,20 @@ def test_upsert_model_version( assert model_version.py.version != mv_proto.name -def test_get_model_version_by_id(model_registry: ModelRegistry, model_version: Mapped): +def test_get_model_version_by_id( + model_registry: ModelRegistry, model: Mapped, model_version: Mapped +): + model.proto.name = f"test_prefix:{model.proto.name}" + art_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + model_version.proto.name = f"1:{model_version.proto.name}" + ctx_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - id = str(id) + model_registry._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=ctx_id, artifact_id=art_id)], [] + ) + id = str(ctx_id) mlmd_mv = model_registry.get_model_version_by_id(id) assert mlmd_mv.id == id assert mlmd_mv.name == model_version.py.name @@ -159,16 +169,20 @@ def test_upsert_model_artifact( assert model.py.name != ma_proto.name -def test_upsert_duplicate_model_artifact( +def test_upsert_duplicate_model_artifact_with_different_version( model_registry: ModelRegistry, model: Mapped, model_version: Mapped ): - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - mv_id = str(mv_id) + mv1_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + mv1_id = str(mv1_id) + + model_version.proto.name = "version2" + mv2_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + mv2_id = str(mv2_id) ma1 = evolve(model.py) - model_registry.upsert_model_artifact(ma1, mv_id) + model_registry.upsert_model_artifact(ma1, mv1_id) ma2 = evolve(model.py) - model_registry.upsert_model_artifact(ma2, mv_id) + model_registry.upsert_model_artifact(ma2, mv2_id) ma_protos = model_registry._store._mlmd_store.get_artifacts_by_id( [int(ma1.id), int(ma2.id)] @@ -178,6 +192,19 @@ def test_upsert_duplicate_model_artifact( assert ma2.name != str(ma_protos[1].name) +def test_upsert_duplicate_model_artifact_with_same_version( + model_registry: ModelRegistry, model: Mapped, model_version: Mapped +): + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + mv_id = str(mv_id) + + ma1 = evolve(model.py) + model_registry.upsert_model_artifact(ma1, mv_id) + ma2 = evolve(model.py) + with raises(StoreException): + model_registry.upsert_model_artifact(ma2, mv_id) + + def test_get_model_artifact_by_id(model_registry: ModelRegistry, model: Mapped): model.proto.name = f"test_prefix:{model.proto.name}" id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] @@ -188,3 +215,41 @@ def test_get_model_artifact_by_id(model_registry: ModelRegistry, model: Mapped): assert mlmd_ma.id == id assert mlmd_ma.name == model.py.name assert mlmd_ma.name != model.proto.name + + +def test_get_model_artifact_by_model_version_id( + model_registry: ModelRegistry, model: Mapped, model_version: Mapped +): + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + ) + + mlmd_ma = model_registry.get_model_artifact_by_params(model_version_id=str(mv_id)) + + assert mlmd_ma.id == str(ma_id) + assert mlmd_ma.name == model.py.name + assert mlmd_ma.name != model.proto.name + + +def test_get_model_artifact_by_external_id( + model_registry: ModelRegistry, model: Mapped +): + model.proto.name = f"test_prefix:{model.proto.name}" + model.proto.external_id = "external_id" + model.py.external_id = "external_id" + + id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + id = str(id) + + mlmd_ma = model_registry.get_model_artifact_by_params( + external_id=model.py.external_id + ) + + assert mlmd_ma.id == id + assert mlmd_ma.name == model.py.name + assert mlmd_ma.name != model.proto.name From d4e9e188d3654a40057ef7bcdf9ad0e406d3571a Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:24 -0300 Subject: [PATCH 108/254] py: add queries for lists Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 89 ++++++++++++++++- clients/python/src/model_registry/__init__.py | 7 +- clients/python/src/model_registry/client.py | 80 ++++++++++++++- .../src/model_registry/store/wrapper.py | 46 ++++++++- .../src/model_registry/types/__init__.py | 4 + .../src/model_registry/types/options.py | 46 +++++++++ clients/python/tests/test_client.py | 99 ++++++++++++++++++- 7 files changed, 357 insertions(+), 14 deletions(-) create mode 100644 clients/python/src/model_registry/types/options.py diff --git a/clients/python/README.md b/clients/python/README.md index e2fcc3d6..f49a5b0d 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -9,6 +9,8 @@ Types are based on [ML Metadata](https://github.com/google/ml-metadata), with Py ## Basic usage +### Create objects + Registry objects can be created by doing @@ -18,14 +20,15 @@ Registry objects can be created by doing from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel trained_model = ModelArtifact("my_model_name", "resource_URI", - description="Model description", - external_id="unique_reference") + description="Model description") version = ModelVersion(trained_model, "v1.0", "model author") model = RegisteredModel("my_model_name") ``` +### Register objects + To register those objects, you can use the [`model_registry.ModelRegistry` class](src/model_registry/registry/client.py): @@ -43,25 +46,101 @@ version_id = registry.upsert_model_version(version, model_id) experiment_id = registry.upsert_model_artifact(trained_model, version_id) ``` -To get previously registered objects from the registry, use +### Query objects + +There are several ways to get previously registered objects from the registry. + +#### By ID + +IDs are created once the object is registered, you can either keep the string returned by the +`upsert_*` functions, or access the `id` property of the objects. + +```py +new_model = RegisteredModel("new_model") + +new_model_id = registry.upsert_registered_model(new_model) + +assert new_model_id == new_model.id +``` + +To query objects using IDs, do + ```py another_model = registry.get_registered_model_by_id("another-model-id") +# fetching a registered_model will also fetch its associated versions +versions = another_model.versions + another_version = registry.get_model_version_by_id("another-version-id", another_model.id) +# fetching a version will also fetch its associated model artifact +model_artifact = another_version.model + another_trained_model = registry.get_model_artifact_by_id("another-model-artifact-id") ``` +#### By parameters + + +External IDs can be used to query objects in the wild. +Note that external IDs must be unique among [artifacts](src/model_registry/types/artifacts.py) or +[contexts](src/model_registry/types/contexts.py). + +```py +trained_model = ModelArtifact("my_model_name", "resource_URI", + description="Model description", + external_id="unique_reference") + +# As a version is a context, we can have the same external_id as the above +version = ModelVersion(trained_model, "v1.0", "model author", + external_id="unique_reference") + +# Registering this will cause an error! +# model = RegisteredModel("my_model_name", +# external_id="unique_reference") + +model = RegisteredModel("my_model_name", + external_id="another_unique_reference") +``` + You can also perform queries by parameters to get model artifacts: ```py -# we can get the model associated to a version +# We can get the model artifact associated to a version another_trained_model = registry.get_model_artifact_by_params(model_version_id=another_version.id) -# or get it by a unique identifier +# Or by its unique identifier trained_model = registry.get_model_artifact_by_params(external_id="unique_reference") ``` +### Query multiple objects + +We can query all objects of a type + +```py +models = registry.get_registered_models() + +versions = registry.get_model_versions("registered_model_id") + +# We can get associated model artifacts with the versions +model_artifacts = [version.model for version in versions] +``` + +To limit or order the query, provide a [`ListOptions`](src/model_registry/types/options.py) object + +```py +from model_registry import ListOptions, OrderByField + +options = ListOptions(limit=50) + +first_50_models = registry.get_registered_models(options) + +# By default we get ascending order +options = ListOptions(order_by=OrderByField.CREATE_TIME, is_asc=False) + +last_50_models = registry.get_registered_models(options) +``` + ## Development Common tasks, such as building documentation and running tests, can be executed using [`nox`](https://github.com/wntrblm/nox) sessions. diff --git a/clients/python/src/model_registry/__init__.py b/clients/python/src/model_registry/__init__.py index cf2429c4..8e0cc026 100644 --- a/clients/python/src/model_registry/__init__.py +++ b/clients/python/src/model_registry/__init__.py @@ -3,5 +3,10 @@ __version__ = "0.0.0" from .client import ModelRegistry +from .types import ListOptions, OrderByField -__all__ = ["ModelRegistry"] +__all__ = [ + "ModelRegistry", + "ListOptions", + "OrderByField", +] diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 76b38cf8..d905c1b1 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -1,15 +1,17 @@ """Client for the model registry. """ +from collections.abc import Sequence from typing import Optional from ml_metadata.proto import Artifact, Context, MetadataStoreClientConfig from .exceptions import StoreException from .store import ProtoType, MLMDStore -from .types import ModelArtifact, ModelVersion, RegisteredModel +from .types import ModelArtifact, ModelVersion, RegisteredModel, ListOptions from .types.artifacts import BaseArtifact from .types.base import Mappable from .types.contexts import BaseContext +from .types.options import MLMDListOptions class ModelRegistry: @@ -123,9 +125,35 @@ def get_registered_model_by_id(self, id: str) -> RegisteredModel: ) py_rm = self._unmap(proto_rm) assert isinstance(py_rm, RegisteredModel), "Expected a registered model" - # TODO: reinsert versions + versions = self.get_model_versions(id) + assert isinstance(versions, list), "Expected a list" + py_rm.versions = versions return py_rm + def get_registered_models( + self, options: Optional[ListOptions] = None + ) -> Sequence[RegisteredModel]: + """Fetch registered models. + + Args: + options (ListOptions, optional): Options for listing registered models. + + Returns: + Sequence[RegisteredModel]: Registered models. + """ + mlmd_options = options.as_mlmd_list_options() if options else None + proto_rms = self._store.get_contexts( + RegisteredModel.get_proto_type_name(), mlmd_options + ) + # using a list comprehension will generate a warning as it can't infer the type for every + # element on the list + py_rms: list[RegisteredModel] = [] + for proto_rm in proto_rms: + py_rm = self._unmap(proto_rm) + assert isinstance(py_rm, RegisteredModel), "Expected a registered model" + py_rms.append(py_rm) + return py_rms + def upsert_model_version( self, model_version: ModelVersion, registered_model_id: str ) -> str: @@ -178,6 +206,32 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: ) return py_mv + def get_model_versions( + self, registered_model_id: str, options: Optional[ListOptions] = None + ) -> Sequence[ModelVersion]: + """Fetch model versions by registered model ID. + + Args: + registered_model_id (str): Registered model ID. + options (ListOptions, optional): Options for listing model versions. + + Returns: + Sequence[ModelVersion]: Model versions. + """ + mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() + mlmd_options.filter_query = f"parent_contexts_a.id = {registered_model_id}" + proto_mvs = self._store.get_contexts( + ModelVersion.get_proto_type_name(), mlmd_options + ) + py_mvs: list[ModelVersion] = [] + for proto_mv in proto_mvs: + py_mv = self._unmap(proto_mv) + assert isinstance(py_mv, ModelVersion), "Expected a model version" + assert py_mv.id is not None, "Model version ID is None" + py_mv.model = self.get_model_artifact_by_params(model_version_id=py_mv.id) + py_mvs.append(py_mv) + return py_mvs + def upsert_model_artifact( self, model_artifact: ModelArtifact, model_version_id: str ) -> None: @@ -261,3 +315,25 @@ def get_model_artifact_by_params( py_ma = self._unmap(proto_ma) assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" return py_ma + + # TODO: does this call make sense? + def get_model_artifacts( + self, + model_version_id: Optional[str] = None, + options: Optional[ListOptions] = None, + ) -> Sequence[ModelArtifact]: + mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() + if model_version_id is not None: + mlmd_options.filter_query = f"contexts_a.id = {model_version_id}" + + proto_mas = self._store.get_artifacts( + ModelArtifact.get_proto_type_name(), mlmd_options + ) + # using a list comprehension will generate a warning as it can't infer the type for every + # element on the list + py_mas: list[ModelArtifact] = [] + for proto_ma in proto_mas: + py_ma = self._unmap(proto_ma) + assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" + py_mas.append(py_ma) + return py_mas diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index f716f50f..ddf6dac1 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -1,7 +1,14 @@ from collections.abc import Sequence from typing import Optional -from ml_metadata import MetadataStore, errors +from ml_metadata import ListOptions, MetadataStore, errors +from ml_metadata.proto import ( + Artifact, + Attribution, + Context, + MetadataStoreClientConfig, + ParentContext, +) from ml_metadata.proto import ( Artifact, Attribution, @@ -152,6 +159,27 @@ def get_context(self, ctx_type_name: str, id: int) -> Context: raise StoreException(f"Context with ID {id} does not exist") + def get_contexts( + self, ctx_type_name: str, options: ListOptions + ) -> Sequence[Context]: + # TODO: should we make options optional? + # if options is not None: + try: + contexts = self._mlmd_store.get_contexts(options) + except errors.InvalidArgumentError as e: + raise StoreError(f"Invalid arguments for get_contexts: {e}") from e + except errors.InternalError as e: + raise ServerError("Couldn't get contexts from MLMD store") from e + + contexts = self._filter_type(ctx_type_name, contexts) + # else: + # contexts = self._mlmd_store.get_contexts_by_type(ctx_type_name) + + if not contexts: + raise StoreError(f"Context type {ctx_type_name} does not exist") + + return contexts + def put_context_parent(self, parent_id: int, child_id: int): """Put a parent-child relationship between two contexts. @@ -245,3 +273,19 @@ def get_attributed_artifact(self, art_type_name: str, ctx_id: int) -> Artifact: if artifacts: return artifacts[0] raise StoreException("No artifacts found") + + def get_artifacts( + self, art_type_name: str, options: ListOptions + ) -> Sequence[Artifact]: + try: + artifacts = self._mlmd_store.get_artifacts(options) + except errors.InvalidArgumentError as e: + raise StoreError(f"Invalid arguments for get_artifacts: {e}") from e + except errors.InternalError as e: + raise ServerError("Couldn't get artifacts from MLMD store") from e + + artifacts = self._filter_type(art_type_name, artifacts) + if not artifacts: + raise StoreError(f"Artifact type {art_type_name} does not exist") + + return artifacts diff --git a/clients/python/src/model_registry/types/__init__.py b/clients/python/src/model_registry/types/__init__.py index e2892122..3009db27 100644 --- a/clients/python/src/model_registry/types/__init__.py +++ b/clients/python/src/model_registry/types/__init__.py @@ -3,6 +3,7 @@ from .artifacts import ModelArtifact, ArtifactState from .contexts import ModelVersion, RegisteredModel +from .options import ListOptions, OrderByField __all__ = [ # Artifacts @@ -11,4 +12,7 @@ # Contexts "ModelVersion", "RegisteredModel", + # Options + "ListOptions", + "OrderByField", ] diff --git a/clients/python/src/model_registry/types/options.py b/clients/python/src/model_registry/types/options.py new file mode 100644 index 00000000..aaae7c5b --- /dev/null +++ b/clients/python/src/model_registry/types/options.py @@ -0,0 +1,46 @@ +"""Options for listing objects. + +Provides a thin wrappers around the options classes defined in the MLMD Py lib. +""" + +from attrs import define, field +from enum import Enum +from typing import Optional + +from ml_metadata import ListOptions as MLMDListOptions +from ml_metadata import OrderByField as MLMDOrderByField + + +class OrderByField(Enum): + """Fields to order by.""" + + CREATE_TIME = MLMDOrderByField.CREATE_TIME + UPDATE_TIME = MLMDOrderByField.UPDATE_TIME + ID = MLMDOrderByField.ID + + +@define +class ListOptions: + """Options for listing objects. + + Attributes: + limit (int): Maximum number of objects to return. + order_by (OrderByField, optional): Field to order by. + is_asc (bool): Whether to order in ascending order. Defaults to True. + """ + + limit: Optional[int] = field(default=None) + order_by: Optional[OrderByField] = field(default=None) + is_asc: bool = field(default=True) + + def as_mlmd_list_options(self) -> MLMDListOptions: + """Convert to MLMD ListOptions. + + Returns: + ListOptions: MLMD ListOptions. + """ + return MLMDListOptions( + limit=self.limit, + order_by=OrderByField(self.order_by).value if self.order_by else None, + is_asc=self.is_asc, + ) diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 315fc7f7..daf9d240 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -9,6 +9,7 @@ Attribution, ContextType, Context, + ParentContext, metadata_store_pb2, ) from model_registry import ModelRegistry @@ -104,17 +105,43 @@ def test_upsert_registered_model( def test_get_registered_model_by_id( - model_registry: ModelRegistry, registered_model: Mapped + model_registry: ModelRegistry, + registered_model: Mapped, + model_version: Mapped, + model: Mapped, ): - id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - id = str(id) + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + + model_version.proto.name = f"1:{model_version.proto.name}" + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + ) + + rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + + model_registry._store._mlmd_store.put_parent_contexts( + [ParentContext(parent_id=rm_id, child_id=mv_id)] + ) - mlmd_rm = model_registry.get_registered_model_by_id(id) - assert mlmd_rm.id == id + mlmd_rm = model_registry.get_registered_model_by_id(str(rm_id)) + assert mlmd_rm.id == str(rm_id) assert mlmd_rm.name == registered_model.py.name assert mlmd_rm.name == registered_model.proto.name +def test_get_registered_models(model_registry: ModelRegistry, registered_model: Mapped): + rm1_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + registered_model.proto.name = "model2" + rm2_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + + mlmd_rms = model_registry.get_registered_models() + assert len(mlmd_rms) == 2 + assert mlmd_rms[0].id in [str(rm1_id), str(rm2_id)] + + def test_upsert_model_version( model_registry: ModelRegistry, model_version: Mapped, registered_model: Mapped ): @@ -151,6 +178,42 @@ def test_get_model_version_by_id( assert mlmd_mv.version != model_version.proto.name +def test_get_model_versions( + model_registry: ModelRegistry, + model_version: Mapped, + registered_model: Mapped, + model: Mapped, +): + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + + rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + + model_version.proto.name = f"{rm_id}:version" + mv1_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + model_version.proto.name = f"{rm_id}:version2" + mv2_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [ + Attribution(context_id=mv1_id, artifact_id=ma_id), + Attribution(context_id=mv2_id, artifact_id=ma_id), + ], + [], + ) + + model_registry._store._mlmd_store.put_parent_contexts( + [ + ParentContext(parent_id=rm_id, child_id=mv1_id), + ParentContext(parent_id=rm_id, child_id=mv2_id), + ] + ) + + mlmd_mvs = model_registry.get_model_versions(str(rm_id)) + assert len(mlmd_mvs) == 2 + assert mlmd_mvs[0].id in [str(mv1_id), str(mv2_id)] + + def test_upsert_model_artifact( monkeypatch, model_registry: ModelRegistry, model: Mapped, model_version: Mapped ): @@ -253,3 +316,29 @@ def test_get_model_artifact_by_external_id( assert mlmd_ma.id == id assert mlmd_ma.name == model.py.name assert mlmd_ma.name != model.proto.name + + +def test_get_model_artifacts( + model_registry: ModelRegistry, model: Mapped, model_version: Mapped +): + mv1_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_version.proto.name = "version2" + mv2_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model.proto.name = "test_prefix:model1" + ma1_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + model.proto.name = "test_prefix:model2" + ma2_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [ + Attribution(context_id=mv1_id, artifact_id=ma1_id), + Attribution(context_id=mv2_id, artifact_id=ma2_id), + ], + [], + ) + + mlmd_mas = model_registry.get_model_artifacts() + assert len(mlmd_mas) == 2 + assert mlmd_mas[0].id in [str(ma1_id), str(ma2_id)] From a07964c74c39c11ebe3cea9ca5c1af175f596ced Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:24 -0300 Subject: [PATCH 109/254] py: add additional params to context query Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 14 ++- clients/python/src/model_registry/client.py | 59 +++++++++++ .../src/model_registry/store/wrapper.py | 22 ++++- clients/python/tests/test_client.py | 97 +++++++++++++++++++ 4 files changed, 188 insertions(+), 4 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index f49a5b0d..f0a32c51 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -103,7 +103,7 @@ model = RegisteredModel("my_model_name", external_id="another_unique_reference") ``` -You can also perform queries by parameters to get model artifacts: +You can also perform queries by parameters: ```py # We can get the model artifact associated to a version @@ -111,6 +111,18 @@ another_trained_model = registry.get_model_artifact_by_params(model_version_id=a # Or by its unique identifier trained_model = registry.get_model_artifact_by_params(external_id="unique_reference") + +# Same thing for a version +version = registry.get_model_version_by_params(external_id="unique_reference") + +# Or for a model +model = registry.get_registered_model_by_params(external_id="another_unique_reference") + +# We can also get a version by its name and associated model id +version = registry.get_model_version_by_params(version="v1.0", registered_model_id="x") + +# And we can get a model by simply calling its name +model = registry.get_registered_model_by_params(name="my_model_name") ``` ### Query multiple objects diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index d905c1b1..fd4b1888 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -130,6 +130,29 @@ def get_registered_model_by_id(self, id: str) -> RegisteredModel: py_rm.versions = versions return py_rm + def get_registered_model_by_params( + self, name: Optional[str] = None, external_id: Optional[str] = None + ) -> RegisteredModel: + """Fetch a registered model by its name or external ID. + + Args: + name (str, optional): Registered model name. + external_id (str, optional): Registered model external ID. + + Returns: + RegisteredModel: Registered model. + """ + if name is None and external_id is None: + raise StoreException("Either name or external_id must be provided") + proto_rm = self._store.get_context( + RegisteredModel.get_proto_type_name(), name=name, external_id=external_id + ) + py_rm = self._unmap(proto_rm) + assert isinstance(py_rm, RegisteredModel), "Expected a registered model" + assert py_rm.id is not None + py_rm.versions = self.get_model_versions(py_rm.id) + return py_rm + def get_registered_models( self, options: Optional[ListOptions] = None ) -> Sequence[RegisteredModel]: @@ -232,6 +255,42 @@ def get_model_versions( py_mvs.append(py_mv) return py_mvs + def get_model_version_by_params( + self, + registered_model_id: Optional[str] = None, + version: Optional[str] = None, + external_id: Optional[str] = None, + ) -> ModelVersion: + """Fetch a model version by associated parameters. + + Either fetches by using external ID or by using registered model ID and version. + + Args: + registered_model_id (str, optional): Registered model ID. + version (str, optional): Model version. + external_id (str, optional): Model version external ID. + + Returns: + ModelVersion: Model version. + """ + if external_id is not None: + proto_mv = self._store.get_context( + ModelVersion.get_proto_type_name(), external_id=external_id + ) + elif registered_model_id is None or version is None: + raise StoreException( + "Either registered_model_id and version or external_id must be provided" + ) + else: + proto_mv = self._store.get_context( + ModelVersion.get_proto_type_name(), + name=f"{registered_model_id}:{version}", + ) + py_mv = self._unmap(proto_mv) + assert isinstance(py_mv, ModelVersion), "Expected a model version" + # TODO: reinsert model + return py_mv + def upsert_model_artifact( self, model_artifact: ModelArtifact, model_version_id: str ) -> None: diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index ddf6dac1..0db1a761 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -138,12 +138,20 @@ def _filter_type( ) -> Sequence[ProtoType]: return [proto for proto in protos if proto.type == type_name] - def get_context(self, ctx_type_name: str, id: int) -> Context: + def get_context(self, ctx_type_name: str, + id: Optional[int] = None, + name: Optional[str] = None, + external_id: Optional[str] = None) -> Context: """Get a context from the store. + This gets a context either by ID, name or external ID. + If multiple arguments are provided, the simplest query will be performed. + Args: ctx_type_name (str): Name of the context type. - id (int): ID of the context. + id (int, optional): ID of the context. + name (str, optional): Name of the context. + external_id (str, optional): External ID of the context. Returns: Context: Context. @@ -151,7 +159,15 @@ def get_context(self, ctx_type_name: str, id: int) -> Context: Raises: StoreException: If the context doesn't exist. """ - contexts = self._mlmd_store.get_contexts_by_id([id]) + if name is not None: + return self._mlmd_store.get_context_by_type_and_name(ctx_type_name, name) + + if id is not None: + contexts = self._mlmd_store.get_contexts_by_id([id]) + elif external_id is not None: + contexts = self._mlmd_store.get_contexts_by_external_ids([external_id]) + else: + raise StoreError("Either id, name or external_id must be provided") contexts = self._filter_type(ctx_type_name, contexts) if contexts: diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index daf9d240..164fd553 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -132,6 +132,69 @@ def test_get_registered_model_by_id( assert mlmd_rm.name == registered_model.proto.name +def test_get_registered_model_by_name( + model_registry: ModelRegistry, + registered_model: Mapped, + model_version: Mapped, + model: Mapped, +): + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + + model_version.proto.name = f"1:{model_version.proto.name}" + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + ) + + rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + + model_registry._store._mlmd_store.put_parent_contexts( + [ParentContext(parent_id=rm_id, child_id=mv_id)] + ) + + mlmd_rm = model_registry.get_registered_model_by_params( + name=registered_model.py.name + ) + assert mlmd_rm.id == str(rm_id) + assert mlmd_rm.name == registered_model.py.name + assert mlmd_rm.name == registered_model.proto.name + + +def test_get_registered_model_by_external_id( + model_registry: ModelRegistry, + registered_model: Mapped, + model_version: Mapped, + model: Mapped, +): + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + + model_version.proto.name = f"1:{model_version.proto.name}" + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + ) + + registered_model.py.external_id = "external_id" + registered_model.proto.external_id = "external_id" + + rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] + + model_registry._store._mlmd_store.put_parent_contexts( + [ParentContext(parent_id=rm_id, child_id=mv_id)] + ) + + mlmd_rm = model_registry.get_registered_model_by_params( + external_id=registered_model.py.external_id + ) + assert mlmd_rm.id == str(rm_id) + assert mlmd_rm.name == registered_model.py.name + assert mlmd_rm.name == registered_model.proto.name + + def test_get_registered_models(model_registry: ModelRegistry, registered_model: Mapped): rm1_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] registered_model.proto.name = "model2" @@ -178,6 +241,40 @@ def test_get_model_version_by_id( assert mlmd_mv.version != model_version.proto.name +def test_get_model_version_by_name( + model_registry: ModelRegistry, model_version: Mapped +): + model_version.proto.name = f"1:{model_version.proto.name}" + + id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + id = str(id) + + mlmd_mv = model_registry.get_model_version_by_params( + registered_model_id="1", version=model_version.py.name + ) + assert mlmd_mv.id == id + assert mlmd_mv.name == model_version.py.name + assert mlmd_mv.name != model_version.proto.name + + +def test_get_model_version_by_external_id( + model_registry: ModelRegistry, model_version: Mapped +): + model_version.proto.name = f"1:{model_version.proto.name}" + model_version.proto.external_id = "external_id" + model_version.py.external_id = "external_id" + + id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + id = str(id) + + mlmd_mv = model_registry.get_model_version_by_params( + external_id=model_version.py.external_id + ) + assert mlmd_mv.id == id + assert mlmd_mv.name == model_version.py.name + assert mlmd_mv.name != model_version.proto.name + + def test_get_model_versions( model_registry: ModelRegistry, model_version: Mapped, From 8f1fe8e05bd5a7b0c813009abc8cea0e002b3123 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:25 -0300 Subject: [PATCH 110/254] workflows: don't generate PR image builds on Python client updates Signed-off-by: Isabella Basso do Amaral --- .github/workflows/build-image-pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index aea18ba1..562545a5 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -10,6 +10,7 @@ on: - '.github/ISSUE_TEMPLATE/**' - '.github/dependabot.yml' - 'docs/**' + - 'clients/python/**' env: QUAY_IMG_REPO: model-registry From 24b3f65a0b0eda7dd9e2ac5ca4d3a101f75943b0 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:25 -0300 Subject: [PATCH 111/254] add GHA workflows for the python client Signed-off-by: Isabella Basso do Amaral --- .github/workflows/constraints.txt | 5 ++ .github/workflows/python-client.yml | 79 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 .github/workflows/constraints.txt create mode 100644 .github/workflows/python-client.yml diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt new file mode 100644 index 00000000..25d0a41b --- /dev/null +++ b/.github/workflows/constraints.txt @@ -0,0 +1,5 @@ +pip==23.3.1 +nox==2023.04.22 +nox-poetry==1.0.2 +poetry==1.6.1 +virtualenv==20.24.6 diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml new file mode 100644 index 00000000..83645bd6 --- /dev/null +++ b/.github/workflows/python-client.yml @@ -0,0 +1,79 @@ +name: Python workflows + +on: + push: + branches: + - "main" + pull_request: + paths: + - "clients/python/**" + +jobs: + tests: + name: ${{ matrix.session }} ${{ matrix.python }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + include: + - { python: "3.10", session: "tests" } + - { python: "3.9", session: "tests" } + - { python: "3.10", session: "docs-build" } + + env: + NOXSESSION: ${{ matrix.session }} + FORCE_COLOR: "1" + PRE_COMMIT_COLOR: "always" + + steps: + - name: Check out the repository + uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python }} + uses: actions/setup-python@v4.6.1 + with: + python-version: ${{ matrix.python }} + + - name: Upgrade pip + run: | + pip install --constraint=.github/workflows/constraints.txt pip + pip --version + + - name: Upgrade pip in virtual environments + shell: python + run: | + import os + import pip + + with open(os.environ["GITHUB_ENV"], mode="a") as io: + print(f"VIRTUALENV_PIP={pip.__version__}", file=io) + + - name: Install Poetry + run: | + pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry + poetry --version + + - name: Install Nox + run: | + pipx install --pip-args=--constraint=.github/workflows/constraints.txt nox + pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry + nox --version + + - name: Run Nox + working-directory: clients/python + run: | + nox --python=${{ matrix.python }} + + - name: Upload coverage data + if: always() && matrix.session == 'tests' + uses: "actions/upload-artifact@v3" + with: + name: coverage-data + path: "clients/python/.coverage.*" + + - name: Upload documentation + if: matrix.session == 'docs-build' + uses: actions/upload-artifact@v3 + with: + name: docs + path: clients/python/docs/_build From 958630a33cac0c5686eb16df5731ab3abcd270e9 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 31 Oct 2023 20:56:25 -0300 Subject: [PATCH 112/254] py: Release v0.1 Signed-off-by: Isabella Basso do Amaral --- clients/python/pyproject.toml | 2 +- clients/python/src/model_registry/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 447218bf..0bfe9476 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "model-registry" -version = "0.0.0" +version = "0.1.0" description = "Client for Red Hat OpenDataHub Model Registry" authors = ["Isabella Basso do Amaral "] license = "Apache-2.0" diff --git a/clients/python/src/model_registry/__init__.py b/clients/python/src/model_registry/__init__.py index 8e0cc026..3801c1ad 100644 --- a/clients/python/src/model_registry/__init__.py +++ b/clients/python/src/model_registry/__init__.py @@ -1,6 +1,6 @@ """Main package for the ODH model registry.""" -__version__ = "0.0.0" +__version__ = "0.1.0" from .client import ModelRegistry from .types import ListOptions, OrderByField From 7218dd9d01298953050bff624c1105abceb76539 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 9 Nov 2023 10:48:05 +0100 Subject: [PATCH 113/254] Implement Model Serving API in the GO Core layer (#128) * extend core api to serving-related operations * add goverter for serving * Implement ServingEnvironment in core and tests * Implement InferenceService in core layer * Bugfix: misc * WIP Test InferenceService * Complete testing for InferenceService * Implement basic ServeModel and WIP tests * Complete ServeModel tests * Implement remaining API and cover with tests * Wire REST api to CORE api calls --------- Co-authored-by: tarilabs --- .../generated/mlmd_openapi_converter.gen.go | 77 + .../generated/openapi_converter.gen.go | 219 +++ .../generated/openapi_mlmd_converter.gen.go | 159 +- .../converter/mlmd_converter_util_test.go | 70 +- internal/converter/mlmd_openapi_converter.go | 18 +- .../converter/mlmd_openapi_converter_util.go | 49 +- internal/converter/opeanpi_converter.go | 18 + internal/converter/openapi_mlmd_converter.go | 39 +- .../converter/openapi_mlmd_converter_util.go | 163 +- internal/core/api.go | 94 +- internal/core/core.go | 653 ++++++- internal/core/core_test.go | 1496 +++++++++++++++++ internal/core/mapper.go | 89 +- .../api_model_registry_service_service.go | 472 +++--- internal/testutils/test_container_utils.go | 24 + 15 files changed, 3307 insertions(+), 333 deletions(-) diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index a7ca2f4a..aaaa04f4 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -11,6 +11,33 @@ import ( type MLMDToOpenAPIConverterImpl struct{} +func (c *MLMDToOpenAPIConverterImpl) ConvertInferenceService(source *proto.Context) (*openapi.InferenceService, error) { + var pOpenapiInferenceService *openapi.InferenceService + if source != nil { + var openapiInferenceService openapi.InferenceService + mapStringOpenapiMetadataValue, err := converter.MapMLMDCustomProperties((*source).CustomProperties) + if err != nil { + return nil, err + } + openapiInferenceService.CustomProperties = &mapStringOpenapiMetadataValue + openapiInferenceService.Description = converter.MapDescription((*source).Properties) + var pString *string + if (*source).ExternalId != nil { + xstring := *(*source).ExternalId + pString = &xstring + } + openapiInferenceService.ExternalID = pString + openapiInferenceService.Name = converter.MapNameFromOwned((*source).Name) + openapiInferenceService.Id = converter.Int64ToString((*source).Id) + openapiInferenceService.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) + openapiInferenceService.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + openapiInferenceService.ModelVersionId = converter.MapPropertyModelVersionId((*source).Properties) + openapiInferenceService.RegisteredModelId = converter.MapPropertyRegisteredModelId((*source).Properties) + openapiInferenceService.ServingEnvironmentId = converter.MapPropertyServingEnvironmentId((*source).Properties) + pOpenapiInferenceService = &openapiInferenceService + } + return pOpenapiInferenceService, nil +} func (c *MLMDToOpenAPIConverterImpl) ConvertModelArtifact(source *proto.Artifact) (*openapi.ModelArtifact, error) { var pOpenapiModelArtifact *openapi.ModelArtifact if source != nil { @@ -106,3 +133,53 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertRegisteredModel(source *proto.Contex } return pOpenapiRegisteredModel, nil } +func (c *MLMDToOpenAPIConverterImpl) ConvertServeModel(source *proto.Execution) (*openapi.ServeModel, error) { + var pOpenapiServeModel *openapi.ServeModel + if source != nil { + var openapiServeModel openapi.ServeModel + openapiServeModel.LastKnownState = converter.MapMLMDServeModelLastKnownState((*source).LastKnownState) + mapStringOpenapiMetadataValue, err := converter.MapMLMDCustomProperties((*source).CustomProperties) + if err != nil { + return nil, err + } + openapiServeModel.CustomProperties = &mapStringOpenapiMetadataValue + openapiServeModel.Description = converter.MapDescription((*source).Properties) + var pString *string + if (*source).ExternalId != nil { + xstring := *(*source).ExternalId + pString = &xstring + } + openapiServeModel.ExternalID = pString + openapiServeModel.Name = converter.MapNameFromOwned((*source).Name) + openapiServeModel.Id = converter.Int64ToString((*source).Id) + openapiServeModel.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) + openapiServeModel.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + openapiServeModel.ModelVersionId = converter.MapPropertyModelVersionIdAsValue((*source).Properties) + pOpenapiServeModel = &openapiServeModel + } + return pOpenapiServeModel, nil +} +func (c *MLMDToOpenAPIConverterImpl) ConvertServingEnvironment(source *proto.Context) (*openapi.ServingEnvironment, error) { + var pOpenapiServingEnvironment *openapi.ServingEnvironment + if source != nil { + var openapiServingEnvironment openapi.ServingEnvironment + mapStringOpenapiMetadataValue, err := converter.MapMLMDCustomProperties((*source).CustomProperties) + if err != nil { + return nil, err + } + openapiServingEnvironment.CustomProperties = &mapStringOpenapiMetadataValue + openapiServingEnvironment.Description = converter.MapDescription((*source).Properties) + var pString *string + if (*source).ExternalId != nil { + xstring := *(*source).ExternalId + pString = &xstring + } + openapiServingEnvironment.ExternalID = pString + openapiServingEnvironment.Name = converter.MapNameFromOwned((*source).Name) + openapiServingEnvironment.Id = converter.Int64ToString((*source).Id) + openapiServingEnvironment.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) + openapiServingEnvironment.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + pOpenapiServingEnvironment = &openapiServingEnvironment + } + return pOpenapiServingEnvironment, nil +} diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index ea22c3c0..e9927185 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -6,6 +6,84 @@ import openapi "github.com/opendatahub-io/model-registry/internal/model/openapi" type OpenAPIConverterImpl struct{} +func (c *OpenAPIConverterImpl) ConvertInferenceServiceCreate(source *openapi.InferenceServiceCreate) (*openapi.InferenceService, error) { + var pOpenapiInferenceService *openapi.InferenceService + if source != nil { + var openapiInferenceService openapi.InferenceService + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiInferenceService.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiInferenceService.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiInferenceService.ExternalID = pString2 + var pString3 *string + if (*source).Name != nil { + xstring3 := *(*source).Name + pString3 = &xstring3 + } + openapiInferenceService.Name = pString3 + var pString4 *string + if (*source).ModelVersionId != nil { + xstring4 := *(*source).ModelVersionId + pString4 = &xstring4 + } + openapiInferenceService.ModelVersionId = pString4 + openapiInferenceService.RegisteredModelId = (*source).RegisteredModelId + openapiInferenceService.ServingEnvironmentId = (*source).ServingEnvironmentId + pOpenapiInferenceService = &openapiInferenceService + } + return pOpenapiInferenceService, nil +} +func (c *OpenAPIConverterImpl) ConvertInferenceServiceUpdate(source *openapi.InferenceServiceUpdate) (*openapi.InferenceService, error) { + var pOpenapiInferenceService *openapi.InferenceService + if source != nil { + var openapiInferenceService openapi.InferenceService + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiInferenceService.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiInferenceService.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiInferenceService.ExternalID = pString2 + var pString3 *string + if (*source).ModelVersionId != nil { + xstring3 := *(*source).ModelVersionId + pString3 = &xstring3 + } + openapiInferenceService.ModelVersionId = pString3 + pOpenapiInferenceService = &openapiInferenceService + } + return pOpenapiInferenceService, nil +} func (c *OpenAPIConverterImpl) ConvertModelArtifactCreate(source *openapi.ModelArtifactCreate) (*openapi.ModelArtifact, error) { var pOpenapiModelArtifact *openapi.ModelArtifact if source != nil { @@ -294,6 +372,147 @@ func (c *OpenAPIConverterImpl) ConvertRegisteredModelUpdate(source *openapi.Regi } return pOpenapiRegisteredModel, nil } +func (c *OpenAPIConverterImpl) ConvertServeModelCreate(source *openapi.ServeModelCreate) (*openapi.ServeModel, error) { + var pOpenapiServeModel *openapi.ServeModel + if source != nil { + var openapiServeModel openapi.ServeModel + var pOpenapiExecutionState *openapi.ExecutionState + if (*source).LastKnownState != nil { + openapiExecutionState := openapi.ExecutionState(*(*source).LastKnownState) + pOpenapiExecutionState = &openapiExecutionState + } + openapiServeModel.LastKnownState = pOpenapiExecutionState + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiServeModel.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiServeModel.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiServeModel.ExternalID = pString2 + var pString3 *string + if (*source).Name != nil { + xstring3 := *(*source).Name + pString3 = &xstring3 + } + openapiServeModel.Name = pString3 + openapiServeModel.ModelVersionId = (*source).ModelVersionId + pOpenapiServeModel = &openapiServeModel + } + return pOpenapiServeModel, nil +} +func (c *OpenAPIConverterImpl) ConvertServeModelUpdate(source *openapi.ServeModelUpdate) (*openapi.ServeModel, error) { + var pOpenapiServeModel *openapi.ServeModel + if source != nil { + var openapiServeModel openapi.ServeModel + var pOpenapiExecutionState *openapi.ExecutionState + if (*source).LastKnownState != nil { + openapiExecutionState := openapi.ExecutionState(*(*source).LastKnownState) + pOpenapiExecutionState = &openapiExecutionState + } + openapiServeModel.LastKnownState = pOpenapiExecutionState + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiServeModel.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiServeModel.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiServeModel.ExternalID = pString2 + pOpenapiServeModel = &openapiServeModel + } + return pOpenapiServeModel, nil +} +func (c *OpenAPIConverterImpl) ConvertServingEnvironmentCreate(source *openapi.ServingEnvironmentCreate) (*openapi.ServingEnvironment, error) { + var pOpenapiServingEnvironment *openapi.ServingEnvironment + if source != nil { + var openapiServingEnvironment openapi.ServingEnvironment + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiServingEnvironment.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiServingEnvironment.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiServingEnvironment.ExternalID = pString2 + var pString3 *string + if (*source).Name != nil { + xstring3 := *(*source).Name + pString3 = &xstring3 + } + openapiServingEnvironment.Name = pString3 + pOpenapiServingEnvironment = &openapiServingEnvironment + } + return pOpenapiServingEnvironment, nil +} +func (c *OpenAPIConverterImpl) ConvertServingEnvironmentUpdate(source *openapi.ServingEnvironmentUpdate) (*openapi.ServingEnvironment, error) { + var pOpenapiServingEnvironment *openapi.ServingEnvironment + if source != nil { + var openapiServingEnvironment openapi.ServingEnvironment + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).CustomProperties != nil { + mapStringOpenapiMetadataValue := make(map[string]openapi.MetadataValue, len((*(*source).CustomProperties))) + for key, value := range *(*source).CustomProperties { + mapStringOpenapiMetadataValue[key] = c.openapiMetadataValueToOpenapiMetadataValue(value) + } + pMapStringOpenapiMetadataValue = &mapStringOpenapiMetadataValue + } + openapiServingEnvironment.CustomProperties = pMapStringOpenapiMetadataValue + var pString *string + if (*source).Description != nil { + xstring := *(*source).Description + pString = &xstring + } + openapiServingEnvironment.Description = pString + var pString2 *string + if (*source).ExternalID != nil { + xstring2 := *(*source).ExternalID + pString2 = &xstring2 + } + openapiServingEnvironment.ExternalID = pString2 + pOpenapiServingEnvironment = &openapiServingEnvironment + } + return pOpenapiServingEnvironment, nil +} func (c *OpenAPIConverterImpl) openapiMetadataValueToOpenapiMetadataValue(source openapi.MetadataValue) openapi.MetadataValue { var openapiMetadataValue openapi.MetadataValue openapiMetadataValue.MetadataBoolValue = c.pOpenapiMetadataBoolValueToPOpenapiMetadataBoolValue(source.MetadataBoolValue) diff --git a/internal/converter/generated/openapi_mlmd_converter.gen.go b/internal/converter/generated/openapi_mlmd_converter.gen.go index 72864b5a..1e3552b6 100755 --- a/internal/converter/generated/openapi_mlmd_converter.gen.go +++ b/internal/converter/generated/openapi_mlmd_converter.gen.go @@ -11,6 +11,51 @@ import ( type OpenAPIToMLMDConverterImpl struct{} +func (c *OpenAPIToMLMDConverterImpl) ConvertInferenceService(source *converter.OpenAPIModelWrapper[openapi.InferenceService]) (*proto.Context, error) { + var pProtoContext *proto.Context + if source != nil { + var protoContext proto.Context + var pString *string + if (*source).Model != nil { + pString = (*source).Model.Id + } + pInt64, err := converter.StringToInt64(pString) + if err != nil { + return nil, fmt.Errorf("error setting field Id: %w", err) + } + protoContext.Id = pInt64 + protoContext.Name = converter.MapInferenceServiceName(source) + pInt642 := (*source).TypeId + protoContext.TypeId = &pInt642 + protoContext.Type = converter.MapInferenceServiceType((*source).Model) + var pString2 *string + if (*source).Model != nil { + pString2 = (*source).Model.ExternalID + } + var pString3 *string + if pString2 != nil { + xstring := *pString2 + pString3 = &xstring + } + protoContext.ExternalId = pString3 + mapStringPProtoValue, err := converter.MapInferenceServiceProperties((*source).Model) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoContext.Properties = mapStringPProtoValue + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).Model != nil { + pMapStringOpenapiMetadataValue = (*source).Model.CustomProperties + } + mapStringPProtoValue2, err := converter.MapOpenAPICustomProperties(pMapStringOpenapiMetadataValue) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoContext.CustomProperties = mapStringPProtoValue2 + pProtoContext = &protoContext + } + return pProtoContext, nil +} func (c *OpenAPIToMLMDConverterImpl) ConvertModelArtifact(source *converter.OpenAPIModelWrapper[openapi.ModelArtifact]) (*proto.Artifact, error) { var pProtoArtifact *proto.Artifact if source != nil { @@ -66,7 +111,11 @@ func (c *OpenAPIToMLMDConverterImpl) ConvertModelArtifact(source *converter.Open if (*source).Model != nil { pOpenapiArtifactState = (*source).Model.State } - protoArtifact.State = converter.MapOpenAPIModelArtifactState(pOpenapiArtifactState) + pProtoArtifact_State, err := converter.MapOpenAPIModelArtifactState(pOpenapiArtifactState) + if err != nil { + return nil, fmt.Errorf("error setting field State: %w", err) + } + protoArtifact.State = pProtoArtifact_State pProtoArtifact = &protoArtifact } return pProtoArtifact, nil @@ -170,3 +219,111 @@ func (c *OpenAPIToMLMDConverterImpl) ConvertRegisteredModel(source *converter.Op } return pProtoContext, nil } +func (c *OpenAPIToMLMDConverterImpl) ConvertServeModel(source *converter.OpenAPIModelWrapper[openapi.ServeModel]) (*proto.Execution, error) { + var pProtoExecution *proto.Execution + if source != nil { + var protoExecution proto.Execution + var pString *string + if (*source).Model != nil { + pString = (*source).Model.Id + } + pInt64, err := converter.StringToInt64(pString) + if err != nil { + return nil, fmt.Errorf("error setting field Id: %w", err) + } + protoExecution.Id = pInt64 + protoExecution.Name = converter.MapServeModelName(source) + pInt642 := (*source).TypeId + protoExecution.TypeId = &pInt642 + protoExecution.Type = converter.MapServeModelType((*source).Model) + var pString2 *string + if (*source).Model != nil { + pString2 = (*source).Model.ExternalID + } + var pString3 *string + if pString2 != nil { + xstring := *pString2 + pString3 = &xstring + } + protoExecution.ExternalId = pString3 + var pOpenapiExecutionState *openapi.ExecutionState + if (*source).Model != nil { + pOpenapiExecutionState = (*source).Model.LastKnownState + } + pProtoExecution_State, err := converter.MapLastKnownState(pOpenapiExecutionState) + if err != nil { + return nil, fmt.Errorf("error setting field LastKnownState: %w", err) + } + protoExecution.LastKnownState = pProtoExecution_State + mapStringPProtoValue, err := converter.MapServeModelProperties((*source).Model) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoExecution.Properties = mapStringPProtoValue + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).Model != nil { + pMapStringOpenapiMetadataValue = (*source).Model.CustomProperties + } + mapStringPProtoValue2, err := converter.MapOpenAPICustomProperties(pMapStringOpenapiMetadataValue) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoExecution.CustomProperties = mapStringPProtoValue2 + pProtoExecution = &protoExecution + } + return pProtoExecution, nil +} +func (c *OpenAPIToMLMDConverterImpl) ConvertServingEnvironment(source *converter.OpenAPIModelWrapper[openapi.ServingEnvironment]) (*proto.Context, error) { + var pProtoContext *proto.Context + if source != nil { + var protoContext proto.Context + var pString *string + if (*source).Model != nil { + pString = (*source).Model.Id + } + pInt64, err := converter.StringToInt64(pString) + if err != nil { + return nil, fmt.Errorf("error setting field Id: %w", err) + } + protoContext.Id = pInt64 + var pString2 *string + if (*source).Model != nil { + pString2 = (*source).Model.Name + } + var pString3 *string + if pString2 != nil { + xstring := *pString2 + pString3 = &xstring + } + protoContext.Name = pString3 + pInt642 := (*source).TypeId + protoContext.TypeId = &pInt642 + protoContext.Type = converter.MapServingEnvironmentType((*source).Model) + var pString4 *string + if (*source).Model != nil { + pString4 = (*source).Model.ExternalID + } + var pString5 *string + if pString4 != nil { + xstring2 := *pString4 + pString5 = &xstring2 + } + protoContext.ExternalId = pString5 + mapStringPProtoValue, err := converter.MapServingEnvironmentProperties((*source).Model) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoContext.Properties = mapStringPProtoValue + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).Model != nil { + pMapStringOpenapiMetadataValue = (*source).Model.CustomProperties + } + mapStringPProtoValue2, err := converter.MapOpenAPICustomProperties(pMapStringOpenapiMetadataValue) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoContext.CustomProperties = mapStringPProtoValue2 + pProtoContext = &protoContext + } + return pProtoContext, nil +} diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index e4ddf882..1d898601 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -297,11 +297,13 @@ func TestMapModelArtifactName(t *testing.T) { func TestMapOpenAPIModelArtifactState(t *testing.T) { assertion := setup(t) - state := MapOpenAPIModelArtifactState(of(openapi.ARTIFACTSTATE_LIVE)) + state, err := MapOpenAPIModelArtifactState(of(openapi.ARTIFACTSTATE_LIVE)) + assertion.Nil(err) assertion.NotNil(state) assertion.Equal(string(openapi.ARTIFACTSTATE_LIVE), state.String()) - state = MapOpenAPIModelArtifactState(nil) + state, err = MapOpenAPIModelArtifactState(nil) + assertion.Nil(err) assertion.Nil(state) } @@ -453,3 +455,67 @@ func TestMapMLMDModelArtifactState(t *testing.T) { artifactState = MapMLMDModelArtifactState(nil) assertion.Nil(artifactState) } + +func TestMapServingEnvironmentType(t *testing.T) { + assertion := setup(t) + + typeName := MapServingEnvironmentType(&openapi.ServingEnvironment{}) + assertion.NotNil(typeName) + assertion.Equal(ServingEnvironmentTypeName, *typeName) +} + +func TestMapInferenceServiceType(t *testing.T) { + assertion := setup(t) + + typeName := MapInferenceServiceType(&openapi.InferenceService{}) + assertion.NotNil(typeName) + assertion.Equal(InferenceServiceTypeName, *typeName) +} + +func TestMapInferenceServiceProperties(t *testing.T) { + assertion := setup(t) + + props, err := MapInferenceServiceProperties(&openapi.InferenceService{ + Description: of("my custom description"), + ModelVersionId: of("1"), + RegisteredModelId: "2", + ServingEnvironmentId: "3", + }) + assertion.Nil(err) + assertion.Equal(4, len(props)) + assertion.Equal("my custom description", props["description"].GetStringValue()) + assertion.Equal(int64(1), props["model_version_id"].GetIntValue()) + assertion.Equal(int64(2), props["registered_model_id"].GetIntValue()) + assertion.Equal(int64(3), props["serving_environment_id"].GetIntValue()) + + // serving and model id must be provided and must be a valid numeric id + props, err = MapInferenceServiceProperties(&openapi.InferenceService{}) + assertion.NotNil(err) + assertion.Equal(0, len(props)) +} + +func TestMapServeModelType(t *testing.T) { + assertion := setup(t) + + typeName := MapServeModelType(&openapi.ServeModel{}) + assertion.NotNil(typeName) + assertion.Equal(ServeModelTypeName, *typeName) +} + +func TestMapServeModelProperties(t *testing.T) { + assertion := setup(t) + + props, err := MapServeModelProperties(&openapi.ServeModel{ + Description: of("my custom description"), + ModelVersionId: "1", + }) + assertion.Nil(err) + assertion.Equal(2, len(props)) + assertion.Equal("my custom description", props["description"].GetStringValue()) + assertion.Equal(int64(1), props["model_version_id"].GetIntValue()) + + // serving and model id must be provided and must be a valid numeric id + props, err = MapServeModelProperties(&openapi.ServeModel{}) + assertion.NotNil(err) + assertion.Equal(0, len(props)) +} diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index a753a538..358e3da3 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -21,7 +21,6 @@ type MLMDToOpenAPIConverter interface { // goverter:map Properties Description | MapDescription ConvertModelVersion(source *proto.Context) (*openapi.ModelVersion, error) - // TODO: map actually ignored properties from Artifact.Properties // goverter:map Name | MapNameFromOwned // goverter:map . ArtifactType | MapArtifactType // goverter:map State | MapMLMDModelArtifactState @@ -33,4 +32,21 @@ type MLMDToOpenAPIConverter interface { // goverter:map Properties StoragePath | MapModelArtifactStoragePath // goverter:map Properties ServiceAccountName | MapModelArtifactServiceAccountName ConvertModelArtifact(source *proto.Artifact) (*openapi.ModelArtifact, error) + + // goverter:map Name | MapNameFromOwned + // goverter:map Properties Description | MapDescription + ConvertServingEnvironment(source *proto.Context) (*openapi.ServingEnvironment, error) + + // goverter:map Name | MapNameFromOwned + // goverter:map Properties Description | MapDescription + // goverter:map Properties ModelVersionId | MapPropertyModelVersionId + // goverter:map Properties RegisteredModelId | MapPropertyRegisteredModelId + // goverter:map Properties ServingEnvironmentId | MapPropertyServingEnvironmentId + ConvertInferenceService(source *proto.Context) (*openapi.InferenceService, error) + + // goverter:map Name | MapNameFromOwned + // goverter:map Properties Description | MapDescription + // goverter:map Properties ModelVersionId | MapPropertyModelVersionIdAsValue + // goverter:map LastKnownState | MapMLMDServeModelLastKnownState + ConvertServeModel(source *proto.Execution) (*openapi.ServeModel, error) } diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 9001af4e..5a2092be 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -93,7 +93,7 @@ func MapMLMDModelArtifactState(source *proto.Artifact_State) *openapi.ArtifactSt return (*openapi.ArtifactState)(&state) } -// MapStringProperty maps proto.Artifact property to specific ModelArtifact string field +// MapStringProperty maps string proto.Value property to specific string field func MapStringProperty(properties map[string]*proto.Value, key string) *string { val, ok := properties[key] if ok { @@ -106,6 +106,26 @@ func MapStringProperty(properties map[string]*proto.Value, key string) *string { return nil } +// MapIntProperty maps int proto.Value property to specific string field +func MapIntProperty(properties map[string]*proto.Value, key string) *string { + val, ok := properties[key] + if ok { + res := val.GetIntValue() + return Int64ToString(&res) + } + + return nil +} + +// MapIntPropertyAsValue maps int proto.Value property to specific string field +func MapIntPropertyAsValue(properties map[string]*proto.Value, key string) string { + val := MapIntProperty(properties, key) + if val != nil { + return *val + } + return "" +} + func MapDescription(properties map[string]*proto.Value) *string { return MapStringProperty(properties, "description") } @@ -133,3 +153,30 @@ func MapModelArtifactStoragePath(properties map[string]*proto.Value) *string { func MapModelArtifactServiceAccountName(properties map[string]*proto.Value) *string { return MapStringProperty(properties, "service_account_name") } + +func MapPropertyModelVersionId(properties map[string]*proto.Value) *string { + return MapIntProperty(properties, "model_version_id") +} + +func MapPropertyModelVersionIdAsValue(properties map[string]*proto.Value) string { + return MapIntPropertyAsValue(properties, "model_version_id") +} + +func MapPropertyRegisteredModelId(properties map[string]*proto.Value) string { + return MapIntPropertyAsValue(properties, "registered_model_id") +} + +func MapPropertyServingEnvironmentId(properties map[string]*proto.Value) string { + return MapIntPropertyAsValue(properties, "serving_environment_id") +} + +// SERVE MODEL + +func MapMLMDServeModelLastKnownState(source *proto.Execution_State) *openapi.ExecutionState { + if source == nil { + return nil + } + + state := source.String() + return (*openapi.ExecutionState)(&state) +} diff --git a/internal/converter/opeanpi_converter.go b/internal/converter/opeanpi_converter.go index 7930f957..74446cdc 100644 --- a/internal/converter/opeanpi_converter.go +++ b/internal/converter/opeanpi_converter.go @@ -25,4 +25,22 @@ type OpenAPIConverter interface { // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch ArtifactType Name ConvertModelArtifactUpdate(source *openapi.ModelArtifactUpdate) (*openapi.ModelArtifact, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertServingEnvironmentCreate(source *openapi.ServingEnvironmentCreate) (*openapi.ServingEnvironment, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Name + ConvertServingEnvironmentUpdate(source *openapi.ServingEnvironmentUpdate) (*openapi.ServingEnvironment, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertInferenceServiceCreate(source *openapi.InferenceServiceCreate) (*openapi.InferenceService, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Name RegisteredModelId ServingEnvironmentId + ConvertInferenceServiceUpdate(source *openapi.InferenceServiceUpdate) (*openapi.InferenceService, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertServeModelCreate(source *openapi.ServeModelCreate) (*openapi.ServeModel, error) + + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Name ModelVersionId + ConvertServeModelUpdate(source *openapi.ServeModelUpdate) (*openapi.ServeModel, error) } diff --git a/internal/converter/openapi_mlmd_converter.go b/internal/converter/openapi_mlmd_converter.go index 7aa905cf..cbab8bf6 100644 --- a/internal/converter/openapi_mlmd_converter.go +++ b/internal/converter/openapi_mlmd_converter.go @@ -6,12 +6,22 @@ import ( ) const ( - RegisteredModelTypeName = "odh.RegisteredModel" - ModelVersionTypeName = "odh.ModelVersion" - ModelArtifactTypeName = "odh.ModelArtifact" + RegisteredModelTypeName = "odh.RegisteredModel" + ModelVersionTypeName = "odh.ModelVersion" + ModelArtifactTypeName = "odh.ModelArtifact" + ServingEnvironmentTypeName = "odh.ServingEnvironment" + InferenceServiceTypeName = "odh.InferenceService" + ServeModelTypeName = "odh.ServeModel" ) -type OpenAPIModelWrapper[M openapi.RegisteredModel | openapi.ModelVersion | openapi.ModelArtifact] struct { +type OpenAPIModelWrapper[ + M openapi.RegisteredModel | + openapi.ModelVersion | + openapi.ModelArtifact | + openapi.ServingEnvironment | + openapi.InferenceService | + openapi.ServeModel, +] struct { TypeId int64 Model *M ParentResourceId *string // optional parent id @@ -47,4 +57,25 @@ type OpenAPIToMLMDConverter interface { // goverter:map Model.State State | MapOpenAPIModelArtifactState // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch ConvertModelArtifact(source *OpenAPIModelWrapper[openapi.ModelArtifact]) (*proto.Artifact, error) + + // goverter:autoMap Model + // goverter:map Model Type | MapServingEnvironmentType + // goverter:map Model Properties | MapServingEnvironmentProperties + // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertServingEnvironment(source *OpenAPIModelWrapper[openapi.ServingEnvironment]) (*proto.Context, error) + + // goverter:autoMap Model + // goverter:map . Name | MapInferenceServiceName + // goverter:map Model Type | MapInferenceServiceType + // goverter:map Model Properties | MapInferenceServiceProperties + // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertInferenceService(source *OpenAPIModelWrapper[openapi.InferenceService]) (*proto.Context, error) + + // goverter:autoMap Model + // goverter:map . Name | MapServeModelName + // goverter:map Model Type | MapServeModelType + // goverter:map Model Properties | MapServeModelProperties + // goverter:map Model.LastKnownState LastKnownState | MapLastKnownState + // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertServeModel(source *OpenAPIModelWrapper[openapi.ServeModel]) (*proto.Execution, error) } diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index 81377019..6595d834 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -133,7 +133,7 @@ func MapRegisteredModelProperties(source *openapi.RegisteredModel) (map[string]* return props, nil } -// MapRegisteredModelType returnd RegisteredModel corresponding MLMD context type +// MapRegisteredModelType return RegisteredModel corresponding MLMD context type func MapRegisteredModelType(_ *openapi.RegisteredModel) *string { return of(RegisteredModelTypeName) } @@ -173,7 +173,7 @@ func MapModelVersionProperties(source *OpenAPIModelWrapper[openapi.ModelVersion] return props, nil } -// MapModelVersionType returnd ModelVersion corresponding MLMD context type +// MapModelVersionType return ModelVersion corresponding MLMD context type func MapModelVersionType(_ *openapi.ModelVersion) *string { return of(ModelVersionTypeName) } @@ -243,7 +243,7 @@ func MapModelArtifactProperties(source *openapi.ModelArtifact) (map[string]*prot return props, nil } -// MapModelArtifactType returnd ModelArtifact corresponding MLMD context type +// MapModelArtifactType return ModelArtifact corresponding MLMD context type func MapModelArtifactType(_ *openapi.ModelArtifact) *string { return of(ModelArtifactTypeName) } @@ -262,13 +262,162 @@ func MapModelArtifactName(source *OpenAPIModelWrapper[openapi.ModelArtifact]) *s return of(PrefixWhenOwned(source.ParentResourceId, artifactName)) } -func MapOpenAPIModelArtifactState(source *openapi.ArtifactState) *proto.Artifact_State { +func MapOpenAPIModelArtifactState(source *openapi.ArtifactState) (*proto.Artifact_State, error) { if source == nil { - return nil + return nil, nil + } + + val, ok := proto.Artifact_State_value[string(*source)] + if !ok { + return nil, fmt.Errorf("invalid artifact state: %s", string(*source)) + } + + return (*proto.Artifact_State)(&val), nil +} + +// SERVING ENVIRONMENT + +// MapServingEnvironmentType return ServingEnvironment corresponding MLMD context type +func MapServingEnvironmentType(_ *openapi.ServingEnvironment) *string { + return of(ServingEnvironmentTypeName) +} + +// MapServingEnvironmentProperties maps ServingEnvironment fields to specific MLMD properties +func MapServingEnvironmentProperties(source *openapi.ServingEnvironment) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + if source != nil { + if source.Description != nil { + props["description"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Description, + }, + } + } + } + return props, nil +} + +// INFERENCE SERVICE + +// MapInferenceServiceType return InferenceService corresponding MLMD context type +func MapInferenceServiceType(_ *openapi.InferenceService) *string { + return of(InferenceServiceTypeName) +} + +// MapInferenceServiceProperties maps InferenceService fields to specific MLMD properties +func MapInferenceServiceProperties(source *openapi.InferenceService) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + if source != nil { + if source.Description != nil { + props["description"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Description, + }, + } + } + + registeredModelId, err := StringToInt64(&source.RegisteredModelId) + if err != nil { + return nil, err + } + props["registered_model_id"] = &proto.Value{ + Value: &proto.Value_IntValue{ + IntValue: *registeredModelId, + }, + } + + servingEnvironmentId, err := StringToInt64(&source.ServingEnvironmentId) + if err != nil { + return nil, err + } + props["serving_environment_id"] = &proto.Value{ + Value: &proto.Value_IntValue{ + IntValue: *servingEnvironmentId, + }, + } + + if source.ModelVersionId != nil { + modelVersionId, err := StringToInt64(source.ModelVersionId) + if err != nil { + return nil, err + } + props["model_version_id"] = &proto.Value{ + Value: &proto.Value_IntValue{ + IntValue: *modelVersionId, + }, + } + } + + } + return props, nil +} + +// MapInferenceServiceName maps the user-provided name into MLMD one, i.e., prefixing it with +// either the parent resource id or a generated uuid +// ref: > InferenceService context is actually a child of ServingEnvironment parent context +func MapInferenceServiceName(source *OpenAPIModelWrapper[openapi.InferenceService]) *string { + return of(PrefixWhenOwned(source.ParentResourceId, *(*source).Model.Name)) +} + +// SERVE MODEL + +// MapServeModelType return ServeModel corresponding MLMD context type +func MapServeModelType(_ *openapi.ServeModel) *string { + return of(ServeModelTypeName) +} + +// MapServeModelProperties maps ServeModel fields to specific MLMD properties +func MapServeModelProperties(source *openapi.ServeModel) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + if source != nil { + if source.Description != nil { + props["description"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Description, + }, + } + } + + modelVersionId, err := StringToInt64(&source.ModelVersionId) + if err != nil { + return nil, err + } + props["model_version_id"] = &proto.Value{ + Value: &proto.Value_IntValue{ + IntValue: *modelVersionId, + }, + } + + } + return props, nil +} + +// MapServeModelName maps the user-provided name into MLMD one, i.e., prefixing it with +// either the parent resource id or a generated uuid. If not provided, autogenerate the name +// itself +func MapServeModelName(source *OpenAPIModelWrapper[openapi.ServeModel]) *string { + // openapi.ServeModel is defined with optional name, so build arbitrary name for this artifact if missing + var serveModelName string + if (*source).Model.Name != nil { + serveModelName = *(*source).Model.Name + } else { + serveModelName = uuid.New().String() + } + return of(PrefixWhenOwned(source.ParentResourceId, serveModelName)) +} + +// MapLastKnownState maps LastKnownState field from ServeModel to Execution +func MapLastKnownState(source *openapi.ExecutionState) (*proto.Execution_State, error) { + if source == nil { + return nil, nil + } + + val, ok := proto.Execution_State_value[string(*source)] + if !ok { + return nil, fmt.Errorf("invalid execution state: %s", string(*source)) } - state := (proto.Artifact_State)(proto.Artifact_State_value[string(*source)]) - return &state + return (*proto.Execution_State)(&val), nil } // of returns a pointer to the provided literal/const input diff --git a/internal/core/api.go b/internal/core/api.go index 20bff21d..3757474c 100644 --- a/internal/core/api.go +++ b/internal/core/api.go @@ -2,9 +2,6 @@ package core import "github.com/opendatahub-io/model-registry/internal/model/openapi" -// Note: for convention, here we are keeping here adherence to the mlmd side -type BaseResourceId int64 - type ListOptions struct { PageSize *int32 OrderBy *string @@ -12,6 +9,7 @@ type ListOptions struct { NextPageToken *string } +// ModelRegistryApi defines the external API for the Model Registry library type ModelRegistryApi interface { // REGISTERED MODEL @@ -19,27 +17,97 @@ type ModelRegistryApi interface { // approach used by MLMD gRPC api. If Id is provided update the entity otherwise create a new one. UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) + // GetRegisteredModelById retrieve RegisteredModel by id GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) + + // GetRegisteredModelByInferenceService retrieve a RegisteredModel by inference service id + GetRegisteredModelByInferenceService(inferenceServiceId string) (*openapi.RegisteredModel, error) + + // GetRegisteredModelByParams find RegisteredModel instances that match the provided optional params GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) + + // GetRegisteredModels return all ModelArtifact properly ordered and sized based on listOptions param. GetRegisteredModels(listOptions ListOptions) (*openapi.RegisteredModelList, error) // MODEL VERSION - // Create a new Model Version - // or update a Model Version associated to a specific RegisteredModel identified by parentResourceId parameter - UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *string) (*openapi.ModelVersion, error) + // UpsertModelVersion create a new Model Version or update a Model Version associated to a + // specific RegisteredModel identified by registeredModelId parameter + UpsertModelVersion(modelVersion *openapi.ModelVersion, registeredModelId *string) (*openapi.ModelVersion, error) + // GetModelVersionById retrieve ModelVersion by id GetModelVersionById(id string) (*openapi.ModelVersion, error) - GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) - GetModelVersions(listOptions ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) + + // GetModelVersionByInferenceService retrieve a ModelVersion by inference service id + GetModelVersionByInferenceService(inferenceServiceId string) (*openapi.ModelVersion, error) + + // GetModelVersionByParams find ModelVersion instances that match the provided optional params + GetModelVersionByParams(versionName *string, registeredModelId *string, externalId *string) (*openapi.ModelVersion, error) + + // GetModelVersions return all ModelArtifact properly ordered and sized based on listOptions param. + // if registeredModelId is provided, return all ModelVersion instances belonging to a specific RegisteredModel + GetModelVersions(listOptions ListOptions, registeredModelId *string) (*openapi.ModelVersionList, error) // MODEL ARTIFACT - // Create a new Artifact - // or update an Artifact associated to a specific ModelVersion identified by parentResourceId parameter - UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *string) (*openapi.ModelArtifact, error) + // UpsertModelArtifact create a new Artifact or update an Artifact associated to a specific + // ModelVersion identified by modelVersionId parameter + UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *string) (*openapi.ModelArtifact, error) + // GetModelArtifactById retrieve ModelArtifact by id GetModelArtifactById(id string) (*openapi.ModelArtifact, error) - GetModelArtifactByParams(artifactName *string, parentResourceId *string, externalId *string) (*openapi.ModelArtifact, error) - GetModelArtifacts(listOptions ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) + + // GetModelArtifactByParams find ModelArtifact instances that match the provided optional params + GetModelArtifactByParams(artifactName *string, modelVersionId *string, externalId *string) (*openapi.ModelArtifact, error) + + // GetModelArtifacts return all ModelArtifact properly ordered and sized based on listOptions param. + // if modelVersionId is provided, return all ModelArtifact instances belonging to a specific ModelVersion + GetModelArtifacts(listOptions ListOptions, modelVersionId *string) (*openapi.ModelArtifactList, error) + + // SERVING ENVIRONMENT + + // UpsertServingEnvironment create or update a serving environmet, the behavior follows the same + // approach used by MLMD gRPC api. If Id is provided update the entity otherwise create a new one. + UpsertServingEnvironment(registeredModel *openapi.ServingEnvironment) (*openapi.ServingEnvironment, error) + + // GetInferenceServiceById retrieve ServingEnvironment by id + GetServingEnvironmentById(id string) (*openapi.ServingEnvironment, error) + + // GetServingEnvironmentByParams find ServingEnvironment instances that match the provided optional params + GetServingEnvironmentByParams(name *string, externalId *string) (*openapi.ServingEnvironment, error) + + // GetServingEnvironments return all ServingEnvironment properly ordered and sized based on listOptions param + GetServingEnvironments(listOptions ListOptions) (*openapi.ServingEnvironmentList, error) + + // INFERENCE SERVICE + + // UpsertInferenceService create or update an inference service, the behavior follows the same + // approach used by MLMD gRPC api. If Id is provided update the entity otherwise create a new one. + // inferenceService.servingEnvironmentId defines the ServingEnvironment to be associated as parent ownership + // to the newly created InferenceService. + UpsertInferenceService(inferenceService *openapi.InferenceService) (*openapi.InferenceService, error) + + // GetInferenceServiceById retrieve InferenceService by id + GetInferenceServiceById(id string) (*openapi.InferenceService, error) + + // GetInferenceServiceByParams find InferenceService instances that match the provided optional params + GetInferenceServiceByParams(name *string, parentResourceId *string, externalId *string) (*openapi.InferenceService, error) + + // GetInferenceServices return all InferenceService properly ordered and sized based on listOptions param + // if servingEnvironmentId is provided, return all InferenceService instances belonging to a specific ServingEnvironment + GetInferenceServices(listOptions ListOptions, servingEnvironmentId *string) (*openapi.InferenceServiceList, error) + + // SERVE MODEL + + // UpsertServeModel create or update a serve model, the behavior follows the same + // approach used by MLMD gRPC api. If Id is provided update the entity otherwise create a new one. + // inferenceServiceId defines the InferenceService to be linked to the newly created ServeModel. + UpsertServeModel(serveModel *openapi.ServeModel, inferenceServiceId *string) (*openapi.ServeModel, error) + + // GetServeModelById retrieve ServeModel by id + GetServeModelById(id string) (*openapi.ServeModel, error) + + // GetServeModels get all ServeModel objects properly ordered and sized based on listOptions param. + // if inferenceServiceId is provided, return all ServeModel instances belonging to a specific InferenceService + GetServeModels(listOptions ListOptions, inferenceServiceId *string) (*openapi.ServeModelList, error) } diff --git a/internal/core/core.go b/internal/core/core.go index 8271cd29..d24913d0 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -12,9 +12,12 @@ import ( ) var ( - registeredModelTypeName = of(converter.RegisteredModelTypeName) - modelVersionTypeName = of(converter.ModelVersionTypeName) - modelArtifactTypeName = of(converter.ModelArtifactTypeName) + registeredModelTypeName = of(converter.RegisteredModelTypeName) + modelVersionTypeName = of(converter.ModelVersionTypeName) + modelArtifactTypeName = of(converter.ModelArtifactTypeName) + servingEnvironmentTypeName = of(converter.ServingEnvironmentTypeName) + inferenceServiceTypeName = of(converter.InferenceServiceTypeName) + serveModelTypeName = of(converter.ServeModelTypeName) ) // modelRegistryService is the core library of the model registry @@ -41,7 +44,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err modelVersionReq := proto.PutContextTypeRequest{ ContextType: &proto.ContextType{ - Name: of(converter.ModelVersionTypeName), + Name: modelVersionTypeName, Properties: map[string]proto.PropertyType{ "description": proto.PropertyType_STRING, "model_name": proto.PropertyType_STRING, @@ -66,23 +69,81 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err }, } + servingEnvironmentReq := proto.PutContextTypeRequest{ + ContextType: &proto.ContextType{ + Name: servingEnvironmentTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + }, + }, + } + + inferenceServiceReq := proto.PutContextTypeRequest{ + ContextType: &proto.ContextType{ + Name: inferenceServiceTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + "model_version_id": proto.PropertyType_INT, + "registered_model_id": proto.PropertyType_INT, + // TODO: check with Andrea, my understanding is parent/child is only for ownership of ServingEnvironment/InferenceService (moving comment down 1 line for serving_environment_id) + // we could remove this as we will use ParentContext to keep track of this association + "serving_environment_id": proto.PropertyType_INT, + }, + }, + } + + serveModelReq := proto.PutExecutionTypeRequest{ + ExecutionType: &proto.ExecutionType{ + Name: serveModelTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + // TODO: check with Andrea, my understanding is parent/child is only for ownership of InferenceService/ServeModel via MLMD Association (Execution ServeModel --> Context InferenceService) + // we could remove this as we will use ParentContext to keep track of this association + "model_version_id": proto.PropertyType_INT, + }, + }, + } + registeredModelResp, err := client.PutContextType(context.Background(), ®isteredModelReq) if err != nil { - glog.Fatalf("Error setting up context type %s: %v", registeredModelTypeName, err) + glog.Fatalf("Error setting up context type %s: %v", *registeredModelTypeName, err) } modelVersionResp, err := client.PutContextType(context.Background(), &modelVersionReq) if err != nil { - glog.Fatalf("Error setting up context type %s: %v", modelVersionTypeName, err) + glog.Fatalf("Error setting up context type %s: %v", *modelVersionTypeName, err) } + modelArtifactResp, err := client.PutArtifactType(context.Background(), &modelArtifactReq) if err != nil { - glog.Fatalf("Error setting up artifact type %s: %v", modelArtifactTypeName, err) + glog.Fatalf("Error setting up artifact type %s: %v", *modelArtifactTypeName, err) + } + + servingEnvironmentResp, err := client.PutContextType(context.Background(), &servingEnvironmentReq) + if err != nil { + glog.Fatalf("Error setting up context type %s: %v", *servingEnvironmentTypeName, err) + } + + inferenceServiceResp, err := client.PutContextType(context.Background(), &inferenceServiceReq) + if err != nil { + glog.Fatalf("Error setting up context type %s: %v", *inferenceServiceTypeName, err) + } + + serveModelResp, err := client.PutExecutionType(context.Background(), &serveModelReq) + if err != nil { + glog.Fatalf("Error setting up execution type %s: %v", *serveModelTypeName, err) } return &modelRegistryService{ mlmdClient: client, - mapper: NewMapper(registeredModelResp.GetTypeId(), modelVersionResp.GetTypeId(), modelArtifactResp.GetTypeId()), + mapper: NewMapper( + registeredModelResp.GetTypeId(), + modelVersionResp.GetTypeId(), + modelArtifactResp.GetTypeId(), + servingEnvironmentResp.GetTypeId(), + inferenceServiceResp.GetTypeId(), + serveModelResp.GetTypeId(), + ), }, nil } @@ -163,6 +224,14 @@ func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.Re return regModel, nil } +func (serv *modelRegistryService) GetRegisteredModelByInferenceService(inferenceServiceId string) (*openapi.RegisteredModel, error) { + is, err := serv.GetInferenceServiceById(inferenceServiceId) + if err != nil { + return nil, err + } + return serv.GetRegisteredModelById(is.RegisteredModelId) +} + func (serv *modelRegistryService) getRegisteredModelByVersionId(id string) (*openapi.RegisteredModel, error) { glog.Info("Getting registered model for model version %s", id) @@ -365,6 +434,27 @@ func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.Model return modelVer, nil } +func (serv *modelRegistryService) GetModelVersionByInferenceService(inferenceServiceId string) (*openapi.ModelVersion, error) { + is, err := serv.GetInferenceServiceById(inferenceServiceId) + if err != nil { + return nil, err + } + if is.ModelVersionId != nil { + return serv.GetModelVersionById(*is.ModelVersionId) + } + // modelVersionId: ID of the ModelVersion to serve. If it's unspecified, then the latest ModelVersion by creation order will be served. + orderByCreateTime := "CREATE_TIME" + sortOrderDesc := "DESC" + versions, err := serv.GetModelVersions(ListOptions{OrderBy: &orderByCreateTime, SortOrder: &sortOrderDesc}, &is.RegisteredModelId) + if err != nil { + return nil, err + } + if len(versions.Items) == 0 { + return nil, fmt.Errorf("no model versions found for id %s", is.RegisteredModelId) + } + return &versions.Items[0], nil +} + func (serv *modelRegistryService) getModelVersionByArtifactId(id string) (*openapi.ModelVersion, error) { glog.Info("Getting model version for model artifact %s", id) @@ -514,7 +604,7 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod return nil, err } - // add explicit association between artifacts and model version + // add explicit Attribution between Artifact and ModelVersion if parentResourceId != nil && modelArtifact.Id == nil { modelVersionId, err := converter.StringToInt64(parentResourceId) if err != nil { @@ -659,6 +749,551 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, par return &toReturn, nil } +// SERVING ENVIRONMENT + +func (serv *modelRegistryService) UpsertServingEnvironment(servingEnvironment *openapi.ServingEnvironment) (*openapi.ServingEnvironment, error) { + var err error + var existing *openapi.ServingEnvironment + + if servingEnvironment.Id == nil { + glog.Info("Creating new serving environment") + } else { + glog.Info("Updating serving environment %s", *servingEnvironment.Id) + existing, err = serv.GetServingEnvironmentById(*servingEnvironment.Id) + if err != nil { + return nil, err + } + } + + // if already existing assure the name is the same + if existing != nil && servingEnvironment.Name == nil { + // user did not provide it + // need to set it to avoid mlmd error "context name should not be empty" + servingEnvironment.Name = existing.Name + } + + protoCtx, err := serv.mapper.MapFromServingEnvironment(servingEnvironment) + if err != nil { + return nil, err + } + + protoCtxResp, err := serv.mlmdClient.PutContexts(context.Background(), &proto.PutContextsRequest{ + Contexts: []*proto.Context{ + protoCtx, + }, + }) + if err != nil { + return nil, err + } + + idAsString := converter.Int64ToString(&protoCtxResp.ContextIds[0]) + openapiModel, err := serv.GetServingEnvironmentById(*idAsString) + if err != nil { + return nil, err + } + + return openapiModel, nil +} + +func (serv *modelRegistryService) GetServingEnvironmentById(id string) (*openapi.ServingEnvironment, error) { + glog.Info("Getting serving environment %s", id) + + idAsInt, err := converter.StringToInt64(&id) + if err != nil { + return nil, err + } + + getByIdResp, err := serv.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*idAsInt}, + }) + if err != nil { + return nil, err + } + + if len(getByIdResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple serving environments found for id %s", id) + } + + if len(getByIdResp.Contexts) == 0 { + return nil, fmt.Errorf("no serving environment found for id %s", id) + } + + openapiModel, err := serv.mapper.MapToServingEnvironment(getByIdResp.Contexts[0]) + if err != nil { + return nil, err + } + + return openapiModel, nil +} + +func (serv *modelRegistryService) GetServingEnvironmentByParams(name *string, externalId *string) (*openapi.ServingEnvironment, error) { + glog.Info("Getting serving environment by params name=%v, externalId=%v", name, externalId) + + filterQuery := "" + if name != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", *name) + } else if externalId != nil { + filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) + } else { + return nil, fmt.Errorf("invalid parameters call, supply either name or externalId") + } + + getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: servingEnvironmentTypeName, + Options: &proto.ListOperationOptions{ + FilterQuery: &filterQuery, + }, + }) + if err != nil { + return nil, err + } + + if len(getByParamsResp.Contexts) != 1 { + return nil, fmt.Errorf("could not find exactly one Context matching criteria: %v", getByParamsResp.Contexts) + } + + openapiModel, err := serv.mapper.MapToServingEnvironment(getByParamsResp.Contexts[0]) + if err != nil { + return nil, err + } + return openapiModel, nil +} + +func (serv *modelRegistryService) GetServingEnvironments(listOptions ListOptions) (*openapi.ServingEnvironmentList, error) { + listOperationOptions, err := BuildListOperationOptions(listOptions) + if err != nil { + return nil, err + } + contextsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: servingEnvironmentTypeName, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + + results := []openapi.ServingEnvironment{} + for _, c := range contextsResp.Contexts { + mapped, err := serv.mapper.MapToServingEnvironment(c) + if err != nil { + return nil, err + } + results = append(results, *mapped) + } + + toReturn := openapi.ServingEnvironmentList{ + NextPageToken: zeroIfNil(contextsResp.NextPageToken), + PageSize: zeroIfNil(listOptions.PageSize), + Size: int32(len(results)), + Items: results, + } + return &toReturn, nil +} + +// INFERENCE SERVICE + +func (serv *modelRegistryService) UpsertInferenceService(inferenceService *openapi.InferenceService) (*openapi.InferenceService, error) { + var err error + var existing *openapi.InferenceService + var servingEnvironment *openapi.ServingEnvironment + // for InferenceService, is part of model payload. + parentResourceId := inferenceService.ServingEnvironmentId + + if inferenceService.Id == nil { + // create + glog.Info("Creating new InferenceService") + servingEnvironment, err = serv.GetServingEnvironmentById(parentResourceId) + if err != nil { + return nil, err + } + } else { + // update + glog.Info("Updating InferenceService %s", *inferenceService.Id) + existing, err = serv.GetInferenceServiceById(*inferenceService.Id) + if err != nil { + return nil, err + } + servingEnvironment, err = serv.getServingEnvironmentByInferenceServiceId(*inferenceService.Id) + if err != nil { + return nil, err + } + } + + // validate RegisteredModelId is also valid + if _, err := serv.GetRegisteredModelById(inferenceService.RegisteredModelId); err != nil { + return nil, err + } + + // if already existing assure the name is the same + if existing != nil && inferenceService.Name == nil { + // user did not provide it + // need to set it to avoid mlmd error "context name should not be empty" + inferenceService.Name = existing.Name + } + + protoCtx, err := serv.mapper.MapFromInferenceService(inferenceService, *servingEnvironment.Id, servingEnvironment.Name) + if err != nil { + return nil, err + } + + protoCtxResp, err := serv.mlmdClient.PutContexts(context.Background(), &proto.PutContextsRequest{ + Contexts: []*proto.Context{ + protoCtx, + }, + }) + if err != nil { + return nil, err + } + + inferenceServiceId := &protoCtxResp.ContextIds[0] + if inferenceService.Id == nil { + servingEnvironmentId, err := converter.StringToInt64(servingEnvironment.Id) + if err != nil { + return nil, err + } + + _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ + ParentContexts: []*proto.ParentContext{{ + ChildId: inferenceServiceId, + ParentId: servingEnvironmentId}}, + TransactionOptions: &proto.TransactionOptions{}, + }) + if err != nil { + return nil, err + } + } + + idAsString := converter.Int64ToString(inferenceServiceId) + toReturn, err := serv.GetInferenceServiceById(*idAsString) + if err != nil { + return nil, err + } + + return toReturn, nil +} + +func (serv *modelRegistryService) getServingEnvironmentByInferenceServiceId(id string) (*openapi.ServingEnvironment, error) { + glog.Info("Getting ServingEnvironment for InferenceService %s", id) + + idAsInt, err := converter.StringToInt64(&id) + if err != nil { + return nil, err + } + + getParentResp, err := serv.mlmdClient.GetParentContextsByContext(context.Background(), &proto.GetParentContextsByContextRequest{ + ContextId: idAsInt, + }) + if err != nil { + return nil, err + } + + if len(getParentResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple ServingEnvironments found for InferenceService %s", id) + } + + if len(getParentResp.Contexts) == 0 { + return nil, fmt.Errorf("no ServingEnvironments found for InferenceService %s", id) + } + + toReturn, err := serv.mapper.MapToServingEnvironment(getParentResp.Contexts[0]) + if err != nil { + return nil, err + } + + return toReturn, nil +} + +func (serv *modelRegistryService) GetInferenceServiceById(id string) (*openapi.InferenceService, error) { + idAsInt, err := converter.StringToInt64(&id) + if err != nil { + return nil, err + } + + getByIdResp, err := serv.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*idAsInt}, + }) + if err != nil { + return nil, err + } + + if len(getByIdResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple InferenceServices found for id %s", id) + } + + if len(getByIdResp.Contexts) == 0 { + return nil, fmt.Errorf("no InferenceService found for id %s", id) + } + + toReturn, err := serv.mapper.MapToInferenceService(getByIdResp.Contexts[0]) + if err != nil { + return nil, err + } + + return toReturn, nil +} + +func (serv *modelRegistryService) GetInferenceServiceByParams(name *string, parentResourceId *string, externalId *string) (*openapi.InferenceService, error) { + filterQuery := "" + if name != nil && parentResourceId != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *name)) + } else if externalId != nil { + filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) + } else { + return nil, fmt.Errorf("invalid parameters call, supply either (name and parentResourceId), or externalId") + } + + getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: inferenceServiceTypeName, + Options: &proto.ListOperationOptions{ + FilterQuery: &filterQuery, + }, + }) + if err != nil { + return nil, err + } + + if len(getByParamsResp.Contexts) != 1 { + return nil, fmt.Errorf("multiple InferenceServices found for name=%v, parentResourceId=%v, externalId=%v", zeroIfNil(name), zeroIfNil(parentResourceId), zeroIfNil(externalId)) + } + + toReturn, err := serv.mapper.MapToInferenceService(getByParamsResp.Contexts[0]) + if err != nil { + return nil, err + } + return toReturn, nil +} + +func (serv *modelRegistryService) GetInferenceServices(listOptions ListOptions, parentResourceId *string) (*openapi.InferenceServiceList, error) { + listOperationOptions, err := BuildListOperationOptions(listOptions) + if err != nil { + return nil, err + } + + if parentResourceId != nil { + queryParentCtxId := fmt.Sprintf("parent_contexts_a.id = %s", *parentResourceId) + listOperationOptions.FilterQuery = &queryParentCtxId + } + + contextsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ + TypeName: inferenceServiceTypeName, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + + results := []openapi.InferenceService{} + for _, c := range contextsResp.Contexts { + mapped, err := serv.mapper.MapToInferenceService(c) + if err != nil { + return nil, err + } + results = append(results, *mapped) + } + + toReturn := openapi.InferenceServiceList{ + NextPageToken: zeroIfNil(contextsResp.NextPageToken), + PageSize: zeroIfNil(listOptions.PageSize), + Size: int32(len(results)), + Items: results, + } + return &toReturn, nil +} + +// SERVE MODEL + +func (serv *modelRegistryService) UpsertServeModel(serveModel *openapi.ServeModel, parentResourceId *string) (*openapi.ServeModel, error) { + var err error + var existing *openapi.ServeModel + + if serveModel.Id == nil { + // create + glog.Info("Creating new ServeModel") + if parentResourceId == nil { + return nil, fmt.Errorf("missing parentResourceId, cannot create ServeModel without parent resource InferenceService") + } + _, err = serv.GetInferenceServiceById(*parentResourceId) + if err != nil { + return nil, err + } + } else { + // update + glog.Info("Updating ServeModel %s", *serveModel.Id) + existing, err = serv.GetServeModelById(*serveModel.Id) + if err != nil { + return nil, err + } + _, err = serv.getInferenceServiceByServeModel(*serveModel.Id) + if err != nil { + return nil, err + } + } + _, err = serv.GetModelVersionById(serveModel.ModelVersionId) + if err != nil { + return nil, err + } + + // if already existing assure the name is the same + if existing != nil && serveModel.Name == nil { + // user did not provide it + // need to set it to avoid mlmd error "artifact name should not be empty" + serveModel.Name = existing.Name + } + + execution, err := serv.mapper.MapFromServeModel(serveModel, *parentResourceId) + if err != nil { + return nil, err + } + + executionsResp, err := serv.mlmdClient.PutExecutions(context.Background(), &proto.PutExecutionsRequest{ + Executions: []*proto.Execution{execution}, + }) + if err != nil { + return nil, err + } + + // add explicit Association between ServeModel and InferenceService + if parentResourceId != nil && serveModel.Id == nil { + inferenceServiceId, err := converter.StringToInt64(parentResourceId) + if err != nil { + return nil, err + } + associations := []*proto.Association{} + for _, a := range executionsResp.ExecutionIds { + associations = append(associations, &proto.Association{ + ContextId: inferenceServiceId, + ExecutionId: &a, + }) + } + _, err = serv.mlmdClient.PutAttributionsAndAssociations(context.Background(), &proto.PutAttributionsAndAssociationsRequest{ + Attributions: make([]*proto.Attribution, 0), + Associations: associations, + }) + if err != nil { + return nil, err + } + } + + idAsString := converter.Int64ToString(&executionsResp.ExecutionIds[0]) + mapped, err := serv.GetServeModelById(*idAsString) + if err != nil { + return nil, err + } + return mapped, nil +} + +func (serv *modelRegistryService) getInferenceServiceByServeModel(id string) (*openapi.InferenceService, error) { + glog.Info("Getting InferenceService for ServeModel %s", id) + + idAsInt, err := converter.StringToInt64(&id) + if err != nil { + return nil, err + } + + getParentResp, err := serv.mlmdClient.GetContextsByExecution(context.Background(), &proto.GetContextsByExecutionRequest{ + ExecutionId: idAsInt, + }) + if err != nil { + return nil, err + } + + if len(getParentResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple InferenceService found for ServeModel %s", id) + } + + if len(getParentResp.Contexts) == 0 { + return nil, fmt.Errorf("no InferenceService found for ServeModel %s", id) + } + + toReturn, err := serv.mapper.MapToInferenceService(getParentResp.Contexts[0]) + if err != nil { + return nil, err + } + + return toReturn, nil +} + +func (serv *modelRegistryService) GetServeModelById(id string) (*openapi.ServeModel, error) { + idAsInt, err := converter.StringToInt64(&id) + if err != nil { + return nil, err + } + + executionsResp, err := serv.mlmdClient.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ + ExecutionIds: []int64{int64(*idAsInt)}, + }) + if err != nil { + return nil, err + } + + if len(executionsResp.Executions) > 1 { + return nil, fmt.Errorf("multiple ServeModels found for id %s", id) + } + + if len(executionsResp.Executions) == 0 { + return nil, fmt.Errorf("no ServeModel found for id %s", id) + } + + result, err := serv.mapper.MapToServeModel(executionsResp.Executions[0]) + if err != nil { + return nil, err + } + + return result, nil +} + +func (serv *modelRegistryService) GetServeModels(listOptions ListOptions, parentResourceId *string) (*openapi.ServeModelList, error) { + listOperationOptions, err := BuildListOperationOptions(listOptions) + if err != nil { + return nil, err + } + + var executions []*proto.Execution + var nextPageToken *string + if parentResourceId != nil { + ctxId, err := converter.StringToInt64(parentResourceId) + if err != nil { + return nil, err + } + executionsResp, err := serv.mlmdClient.GetExecutionsByContext(context.Background(), &proto.GetExecutionsByContextRequest{ + ContextId: ctxId, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + executions = executionsResp.Executions + nextPageToken = executionsResp.NextPageToken + } else { + executionsResp, err := serv.mlmdClient.GetExecutionsByType(context.Background(), &proto.GetExecutionsByTypeRequest{ + TypeName: serveModelTypeName, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + executions = executionsResp.Executions + nextPageToken = executionsResp.NextPageToken + } + + results := []openapi.ServeModel{} + for _, a := range executions { + mapped, err := serv.mapper.MapToServeModel(a) + if err != nil { + return nil, err + } + results = append(results, *mapped) + } + + toReturn := openapi.ServeModelList{ + NextPageToken: zeroIfNil(nextPageToken), + PageSize: zeroIfNil(listOptions.PageSize), + Size: int32(len(results)), + Items: results, + } + return &toReturn, nil +} + // of returns a pointer to the provided literal/const input func of[E any](e E) *E { return &e diff --git a/internal/core/core_test.go b/internal/core/core_test.go index c2f4073b..85c3bb29 100644 --- a/internal/core/core_test.go +++ b/internal/core/core_test.go @@ -34,6 +34,13 @@ var ( artifactExtId string artifactState string artifactUri string + // entity under test + entityName string + entityExternalId string + entityExternalId2 string + entityDescription string + // ServeModel + executionState string ) func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { @@ -53,6 +60,11 @@ func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataSt artifactExtId = "org.myawesomemodel@v1:pickle" artifactState = "LIVE" artifactUri = "path/to/model/v1" + entityName = "MyAwesomeEntity" + entityExternalId = "entityExternalID" + entityExternalId2 = "entityExternalID2" + entityDescription = "lorem ipsum entity description" + executionState = "RUNNING" conn, client, teardown := testutils.SetupMLMDTestContainer(t) return assert.New(t), conn, client, teardown @@ -95,6 +107,38 @@ func registerModel(assertion *assert.Assertions, service ModelRegistryApi, overr return *createdModel.Id } +// utility function that register a new simple ServingEnvironment and return its ID +func registerServingEnvironment(assertion *assert.Assertions, service ModelRegistryApi, overrideName *string, overrideExternalId *string) string { + eutName := "Simple ServingEnvironment" + eutExtID := "Simple ServingEnvironment ExtID" + eut := &openapi.ServingEnvironment{ + Name: &eutName, + ExternalID: &eutExtID, + Description: &entityDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, + } + + if overrideName != nil { + eut.Name = overrideName + } + + if overrideExternalId != nil { + eut.ExternalID = overrideExternalId + } + + // test + createdEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + return *createdEntity.Id +} + // utility function that register a new simple model and return its ID func registerModelVersion( assertion *assert.Assertions, @@ -133,6 +177,40 @@ func registerModelVersion( return *createdVersion.Id } +// utility function that register a new simple ServingEnvironment and return its ID +func registerInferenceService(assertion *assert.Assertions, service ModelRegistryApi, registerdModelId string, overrideParentResourceName *string, overrideParentResourceExternalId *string, overrideName *string, overrideExternalId *string) string { + servingEnvironmentId := registerServingEnvironment(assertion, service, overrideParentResourceName, overrideParentResourceExternalId) + + eutName := "simpleInferenceService" + eutExtID := "simpleInferenceService ExtID" + eut := &openapi.InferenceService{ + Name: &eutName, + ExternalID: &eutExtID, + RegisteredModelId: registerdModelId, + ServingEnvironmentId: servingEnvironmentId, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, + } + + if overrideName != nil { + eut.Name = overrideName + } + if overrideExternalId != nil { + eut.ExternalID = overrideExternalId + } + + // test + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating InferenceService: %v", err) + + return *createdEntity.Id +} + func TestModelRegistryTypes(t *testing.T) { assertion, conn, client, teardown := setup(t) defer teardown(t) @@ -1431,3 +1509,1421 @@ func TestGetModelArtifacts(t *testing.T) { assertion.Equal(*converter.Int64ToString(createdArtifactId2), *getAllByModelVersion.Items[1].Id) assertion.Equal(*converter.Int64ToString(createdArtifactId3), *getAllByModelVersion.Items[0].Id) } + +// SERVING ENVIRONMENT + +func TestCreateServingEnvironment(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + Description: &entityDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, + } + + // test + createdEntity, err := service.UpsertServingEnvironment(eut) + + // checks + assertion.Nilf(err, "error creating uut: %v", err) + assertion.NotNilf(createdEntity.Id, "created uut should not have nil Id") + + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*createdEntityId}, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + ctxId := converter.Int64ToString(ctx.Id) + assertion.Equal(*createdEntity.Id, *ctxId, "returned id should match the mlmd one") + assertion.Equal(entityName, *ctx.Name, "saved name should match the provided one") + assertion.Equal(entityExternalId, *ctx.ExternalId, "saved external id should match the provided one") + assertion.Equal(entityDescription, ctx.Properties["description"].GetStringValue(), "saved description should match the provided one") + assertion.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") +} + +func TestUpdateServingEnvironment(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, + } + + // test + createdEntity, err := service.UpsertServingEnvironment(eut) + + // checks + assertion.Nilf(err, "error creating uut: %v", err) + assertion.NotNilf(createdEntity.Id, "created uut should not have nil Id") + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + // checks created entity matches original one except for Id + assertion.Equal(*eut.Name, *createdEntity.Name, "returned entity should match the original one") + assertion.Equal(*eut.ExternalID, *createdEntity.ExternalID, "returned entity external id should match the original one") + assertion.Equal(*eut.CustomProperties, *createdEntity.CustomProperties, "returned entity custom props should match the original one") + + // update existing entity + newExternalId := "newExternalId" + newOwner := "newOwner" + + createdEntity.ExternalID = &newExternalId + (*createdEntity.CustomProperties)["owner"] = openapi.MetadataValue{ + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &newOwner, + }, + } + + // update the entity + createdEntity, err = service.UpsertServingEnvironment(createdEntity) + assertion.Nilf(err, "error creating uut: %v", err) + + // still one expected MLMD type + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*createdEntityId}, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + ctxId := converter.Int64ToString(ctx.Id) + assertion.Equal(*createdEntity.Id, *ctxId, "returned entity id should match the mlmd one") + assertion.Equal(entityName, *ctx.Name, "saved entity name should match the provided one") + assertion.Equal(newExternalId, *ctx.ExternalId, "saved external id should match the provided one") + assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + + // update the entity under test, keeping nil name + newExternalId = "newNewExternalId" + createdEntity.ExternalID = &newExternalId + createdEntity.Name = nil + createdEntity, err = service.UpsertServingEnvironment(createdEntity) + assertion.Nilf(err, "error creating entity: %v", err) + + // still one registered entity + getAllResp, err = client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + + ctxById, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{*createdEntityId}, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + + ctx = ctxById.Contexts[0] + ctxId = converter.Int64ToString(ctx.Id) + assertion.Equal(*createdEntity.Id, *ctxId, "returned entity id should match the mlmd one") + assertion.Equal(entityName, *ctx.Name, "saved entity name should match the provided one") + assertion.Equal(newExternalId, *ctx.ExternalId, "saved external id should match the provided one") + assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") +} + +func TestGetServingEnvironmentById(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new entity + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + CustomProperties: &map[string]openapi.MetadataValue{ + "owner": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &owner, + }, + }, + }, + } + + // test + createdEntity, err := service.UpsertServingEnvironment(eut) + + // checks + assertion.Nilf(err, "error creating eut: %v", err) + + getEntityById, err := service.GetServingEnvironmentById(*createdEntity.Id) + assertion.Nilf(err, "error getting eut by id %s: %v", *createdEntity.Id, err) + + // checks created entity matches original one except for Id + assertion.Equal(*eut.Name, *getEntityById.Name, "saved name should match the original one") + assertion.Equal(*eut.ExternalID, *getEntityById.ExternalID, "saved external id should match the original one") + assertion.Equal(*eut.CustomProperties, *getEntityById.CustomProperties, "saved custom props should match the original one") +} + +func TestGetServingEnvironmentByParamsName(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + } + + createdEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + byName, err := service.GetServingEnvironmentByParams(&entityName, nil) + assertion.Nilf(err, "error getting ServingEnvironment by name: %v", err) + + assertion.Equalf(*createdEntity.Id, *byName.Id, "the returned entity id should match the retrieved by name") +} + +func TestGetServingEnvironmentByParamsExternalId(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + } + + createdEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + byName, err := service.GetServingEnvironmentByParams(nil, &entityExternalId) + assertion.Nilf(err, "error getting ServingEnvironment by external id: %v", err) + + assertion.Equalf(*createdEntity.Id, *byName.Id, "the returned entity id should match the retrieved by name") +} + +func TestGetServingEnvironmentByEmptyParams(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + } + + _, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + _, err = service.GetServingEnvironmentByParams(nil, nil) + assertion.NotNil(err) + assertion.Equal("invalid parameters call, supply either name or externalId", err.Error()) +} + +func TestGetServingEnvironmentsOrderedById(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + orderBy := "ID" + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + } + + _, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + newName := "Pricingentity2" + newExternalId := "myExternalId2" + eut.Name = &newName + eut.ExternalID = &newExternalId + _, err = service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + newName = "Pricingentity3" + newExternalId = "myExternalId3" + eut.Name = &newName + eut.ExternalID = &newExternalId + _, err = service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + orderedById, err := service.GetServingEnvironments(ListOptions{ + OrderBy: &orderBy, + SortOrder: &ascOrderDirection, + }) + assertion.Nilf(err, "error getting ServingEnvironment: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + for i := 0; i < int(orderedById.Size)-1; i++ { + assertion.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + } + + orderedById, err = service.GetServingEnvironments(ListOptions{ + OrderBy: &orderBy, + SortOrder: &descOrderDirection, + }) + assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + for i := 0; i < int(orderedById.Size)-1; i++ { + assertion.Greater(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + } +} + +func TestGetServingEnvironmentsOrderedByLastUpdate(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + orderBy := "LAST_UPDATE_TIME" + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + } + + firstEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + newName := "Pricingentity2" + newExternalId := "myExternalId2" + eut.Name = &newName + eut.ExternalID = &newExternalId + secondEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + newName = "Pricingentity3" + newExternalId = "myExternalId3" + eut.Name = &newName + eut.ExternalID = &newExternalId + thirdEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + // update second entity + secondEntity.ExternalID = nil + _, err = service.UpsertServingEnvironment(secondEntity) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + orderedById, err := service.GetServingEnvironments(ListOptions{ + OrderBy: &orderBy, + SortOrder: &ascOrderDirection, + }) + assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + assertion.Equal(*firstEntity.Id, *orderedById.Items[0].Id) + assertion.Equal(*thirdEntity.Id, *orderedById.Items[1].Id) + assertion.Equal(*secondEntity.Id, *orderedById.Items[2].Id) + + orderedById, err = service.GetServingEnvironments(ListOptions{ + OrderBy: &orderBy, + SortOrder: &descOrderDirection, + }) + assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + + assertion.Equal(3, int(orderedById.Size)) + assertion.Equal(*secondEntity.Id, *orderedById.Items[0].Id) + assertion.Equal(*thirdEntity.Id, *orderedById.Items[1].Id) + assertion.Equal(*firstEntity.Id, *orderedById.Items[2].Id) +} + +func TestGetServingEnvironmentsWithPageSize(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + pageSize := int32(1) + pageSize2 := int32(2) + entityName := "Pricingentity1" + entityExternalId := "myExternalId1" + + // register a new ServingEnvironment + eut := &openapi.ServingEnvironment{ + Name: &entityName, + ExternalID: &entityExternalId, + } + + firstEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating registered entity: %v", err) + + newName := "Pricingentity2" + newExternalId := "myExternalId2" + eut.Name = &newName + eut.ExternalID = &newExternalId + secondEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + newName = "Pricingentity3" + newExternalId = "myExternalId3" + eut.Name = &newName + eut.ExternalID = &newExternalId + thirdEntity, err := service.UpsertServingEnvironment(eut) + assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + + truncatedList, err := service.GetServingEnvironments(ListOptions{ + PageSize: &pageSize, + }) + assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + + assertion.Equal(1, int(truncatedList.Size)) + assertion.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") + assertion.Equal(*firstEntity.Id, *truncatedList.Items[0].Id) + + truncatedList, err = service.GetServingEnvironments(ListOptions{ + PageSize: &pageSize2, + NextPageToken: &truncatedList.NextPageToken, + }) + assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + + assertion.Equal(2, int(truncatedList.Size)) + assertion.Equal("", truncatedList.NextPageToken, "next page token should be empty as list item returned") + assertion.Equal(*secondEntity.Id, *truncatedList.Items[0].Id) + assertion.Equal(*thirdEntity.Id, *truncatedList.Items[1].Id) +} + +// INFERENCE SERVICE + +func TestCreateInferenceService(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdEntityId, + }, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + + assertion.Equal(*createdEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") + assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, entityName), *byId.Contexts[0].Name, "saved name should match the provided one") + assertion.Equal(entityExternalId2, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(entityDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") + assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) + + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + assertion.Equal(3, len(getAllResp.Contexts), "there should be 3 contexts (RegisteredModel, ServingEnvironment, InferenceService) saved in mlmd") +} + +func TestCreateInferenceServiceFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + ServingEnvironmentId: "9999", + RegisteredModelId: "9998", + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + _, err := service.UpsertInferenceService(eut) + assertion.NotNil(err) + assertion.Equal("no serving environment found for id 9999", err.Error()) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + eut.ServingEnvironmentId = parentResourceId + + _, err = service.UpsertInferenceService(eut) + assertion.NotNil(err) + assertion.Equal("no registered model found for id 9998", err.Error()) +} + +func TestUpdateInferenceService(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + newExternalId := "org.my_awesome_entity@v1" + newScore := 0.95 + + createdEntity.ExternalID = &newExternalId + (*createdEntity.CustomProperties)["score"] = openapi.MetadataValue{ + MetadataDoubleValue: &openapi.MetadataDoubleValue{ + DoubleValue: &newScore, + }, + } + + updatedEntity, err := service.UpsertInferenceService(createdEntity) + assertion.Nilf(err, "error updating new entity for %s: %v", registeredModelId, err) + + updateEntityId, _ := converter.StringToInt64(updatedEntity.Id) + assertion.Equal(*createdEntityId, *updateEntityId, "created and updated should have same id") + + byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *updateEntityId, + }, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + assertion.Equal(1, len(byId.Contexts), "there should be 1 context saved in mlmd by id") + + assertion.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") + assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") + assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) + + getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) + assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + fmt.Printf("%+v", getAllResp.Contexts) + assertion.Equal(3, len(getAllResp.Contexts), "there should be 3 contexts saved in mlmd") + + // update with nil name + newExternalId = "org.my_awesome_entity_@v1" + updatedEntity.ExternalID = &newExternalId + updatedEntity.Name = nil + updatedEntity, err = service.UpsertInferenceService(updatedEntity) + assertion.Nilf(err, "error updating new model version for %s: %v", updateEntityId, err) + + updateEntityId, _ = converter.StringToInt64(updatedEntity.Id) + assertion.Equal(*createdEntityId, *updateEntityId, "created and updated should have same id") + + byId, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *updateEntityId, + }, + }) + assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + assertion.Equal(1, len(byId.Contexts), "there should be 1 context saved in mlmd by id") + + assertion.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") + assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") + assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) +} + +func TestUpdateInferenceServiceFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + + newExternalId := "org.my_awesome_entity@v1" + newScore := 0.95 + + createdEntity.ExternalID = &newExternalId + (*createdEntity.CustomProperties)["score"] = openapi.MetadataValue{ + MetadataDoubleValue: &openapi.MetadataDoubleValue{ + DoubleValue: &newScore, + }, + } + + wrongId := "9999" + createdEntity.Id = &wrongId + _, err = service.UpsertInferenceService(createdEntity) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("no InferenceService found for id %s", wrongId), err.Error()) +} + +func TestGetInferenceServiceById(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + getById, err := service.GetInferenceServiceById(*createdEntity.Id) + assertion.Nilf(err, "error getting model version with id %d", *createdEntityId) + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdEntityId, + }, + }) + assertion.Nilf(err, "error retrieving context, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + assertion.Equal(*getById.Id, *converter.Int64ToString(ctx.Id), "returned id should match the mlmd context one") + assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getById.Name), *ctx.Name, "saved name should match the provided one") + assertion.Equal(*getById.ExternalID, *eut.ExternalID, "saved external id should match the provided one") + assertion.Equal(*(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, author, "saved author custom property should match the provided one") +} + +func TestGetRegisteredModelByInferenceServiceId(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + getRM, err := service.GetRegisteredModelByInferenceService(*createdEntity.Id) + assertion.Nilf(err, "error getting using id %d", *createdEntityId) + + assertion.Equal(registeredModelId, *getRM.Id, "returned id should match the original registeredModelId") +} + +func TestGetModelVersionByInferenceServiceId(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + // todo + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + modelVersion1Name := "v1" + modelVersion1 := &openapi.ModelVersion{Name: &modelVersion1Name, Description: &modelVersionDescription} + createdVersion1, err := service.UpsertModelVersion(modelVersion1, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersion1Id := *createdVersion1.Id + + modelVersion2Name := "v2" + modelVersion2 := &openapi.ModelVersion{Name: &modelVersion2Name, Description: &modelVersionDescription} + createdVersion2, err := service.UpsertModelVersion(modelVersion2, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersion2Id := *createdVersion2.Id + // end of data preparation + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + ModelVersionId: nil, // first we test by unspecified + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + getVModel, err := service.GetModelVersionByInferenceService(*createdEntity.Id) + assertion.Nilf(err, "error getting using id %d", *createdEntityId) + assertion.Equal(createdVersion2Id, *getVModel.Id, "returned id shall be the latest ModelVersion by creation order") + + // here we used the returned entity (so ID is populated), and we update to specify the "ID of the ModelVersion to serve" + createdEntity.ModelVersionId = &createdVersion1Id + _, err = service.UpsertInferenceService(createdEntity) + assertion.Nilf(err, "error updating eut for %v", parentResourceId) + + getVModel, err = service.GetModelVersionByInferenceService(*createdEntity.Id) + assertion.Nilf(err, "error getting using id %d", *createdEntityId) + assertion.Equal(createdVersion1Id, *getVModel.Id, "returned id shall be the specified one") +} + +func TestGetInferenceServiceByParamsName(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + getByName, err := service.GetInferenceServiceByParams(&entityName, &parentResourceId, nil) + assertion.Nilf(err, "error getting model version by name %d", *createdEntityId) + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdEntityId, + }, + }) + assertion.Nilf(err, "error retrieving context, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + assertion.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned id should match the mlmd context one") + assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByName.Name), *ctx.Name, "saved name should match the provided one") + assertion.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") + assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByName.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") +} + +func TestGetInfernenceServiceByParamsExternalId(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + + getByExternalId, err := service.GetInferenceServiceByParams(nil, nil, eut.ExternalID) + assertion.Nilf(err, "error getting by external id %d", *eut.ExternalID) + + ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ContextIds: []int64{ + *createdEntityId, + }, + }) + assertion.Nilf(err, "error retrieving context, not related to the test itself: %v", err) + + ctx := ctxById.Contexts[0] + assertion.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned id should match the mlmd context one") + assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByExternalId.Name), *ctx.Name, "saved name should match the provided one") + assertion.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") + assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByExternalId.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") +} + +func TestGetInferenceServiceByEmptyParams(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertInferenceService(eut) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + + _, err = service.GetInferenceServiceByParams(nil, nil, nil) + assertion.NotNil(err) + assertion.Equal("invalid parameters call, supply either (name and parentResourceId), or externalId", err.Error()) +} + +func TestGetInferenceServices(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + registeredModelId := registerModel(assertion, service, nil, nil) + + eut1 := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + } + + secondName := "v2" + secondExtId := "org.myawesomeentity@v2" + eut2 := &openapi.InferenceService{ + Name: &secondName, + ExternalID: &secondExtId, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + } + + thirdName := "v3" + thirdExtId := "org.myawesomeentity@v3" + eut3 := &openapi.InferenceService{ + Name: &thirdName, + ExternalID: &thirdExtId, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + } + + createdEntity1, err := service.UpsertInferenceService(eut1) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + createdEntity2, err := service.UpsertInferenceService(eut2) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + createdEntity3, err := service.UpsertInferenceService(eut3) + assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + + anotherParentResourceName := "AnotherModel" + anotherParentResourceExtId := "org.another" + anotherParentResourceId := registerServingEnvironment(assertion, service, &anotherParentResourceName, &anotherParentResourceExtId) + + anotherName := "v1.0" + anotherExtId := "org.another@v1.0" + eutAnother := &openapi.InferenceService{ + Name: &anotherName, + ExternalID: &anotherExtId, + ServingEnvironmentId: anotherParentResourceId, + RegisteredModelId: registeredModelId, + } + + _, err = service.UpsertInferenceService(eutAnother) + assertion.Nilf(err, "error creating new model version for %d", anotherParentResourceId) + + createdId1, _ := converter.StringToInt64(createdEntity1.Id) + createdId2, _ := converter.StringToInt64(createdEntity2.Id) + createdId3, _ := converter.StringToInt64(createdEntity3.Id) + + getAll, err := service.GetInferenceServices(ListOptions{}, nil) + assertion.Nilf(err, "error getting all") + assertion.Equal(int32(4), getAll.Size, "expected 4 across all parent resources") + + getAllByParentResource, err := service.GetInferenceServices(ListOptions{}, &parentResourceId) + assertion.Nilf(err, "error getting all") + assertion.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) + + assertion.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[2].Id) + + // order by last update time, expecting last created as first + orderByLastUpdate := "LAST_UPDATE_TIME" + getAllByParentResource, err = service.GetInferenceServices(ListOptions{ + OrderBy: &orderByLastUpdate, + SortOrder: &descOrderDirection, + }, &parentResourceId) + assertion.Nilf(err, "error getting all") + assertion.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) + + assertion.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[0].Id) + + // update the second entity + newExternalId := "updated.org:v2" + createdEntity2.ExternalID = &newExternalId + createdEntity2, err = service.UpsertInferenceService(createdEntity2) + assertion.Nilf(err, "error creating new eut2 for %d", parentResourceId) + + assertion.Equal(newExternalId, *createdEntity2.ExternalID) + + getAllByParentResource, err = service.GetInferenceServices(ListOptions{ + OrderBy: &orderByLastUpdate, + SortOrder: &descOrderDirection, + }, &parentResourceId) + assertion.Nilf(err, "error getting all") + assertion.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) + + assertion.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[1].Id) +} + +// SERVE MODEL + +func TestCreateServeModel(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + Description: &modelVersionDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersionId := *createdVersion.Id + createdVersionIdAsInt, _ := converter.StringToInt64(&createdVersionId) + // end of data preparation + + eut := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + ExternalID: &entityExternalId2, + Description: &entityDescription, + Name: &entityName, + ModelVersionId: createdVersionId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) + assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + assertion.NotNil(createdEntity.Id, "created id should not be nil") + + state, _ := openapi.NewExecutionStateFromValue(executionState) + assertion.Equal(entityName, *createdEntity.Name) + assertion.Equal(*state, *createdEntity.LastKnownState) + assertion.Equal(createdVersionId, createdEntity.ModelVersionId) + assertion.Equal(entityDescription, *createdEntity.Description) + assertion.Equal(author, *(*createdEntity.CustomProperties)["author"].MetadataStringValue.StringValue) + + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + getById, err := client.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ + ExecutionIds: []int64{*createdEntityId}, + }) + assertion.Nilf(err, "error getting Execution by id %d", createdEntityId) + + assertion.Equal(*createdEntityId, *getById.Executions[0].Id) + assertion.Equal(fmt.Sprintf("%s:%s", inferenceServiceId, *createdEntity.Name), *getById.Executions[0].Name) + assertion.Equal(string(*createdEntity.LastKnownState), getById.Executions[0].LastKnownState.String()) + assertion.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) + assertion.Equal(*createdEntity.Description, getById.Executions[0].Properties["description"].GetStringValue()) + assertion.Equal(*(*createdEntity.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["author"].GetStringValue()) + + inferenceServiceIdAsInt, _ := converter.StringToInt64(&inferenceServiceId) + byCtx, _ := client.GetExecutionsByContext(context.Background(), &proto.GetExecutionsByContextRequest{ + ContextId: (*int64)(inferenceServiceIdAsInt), + }) + assertion.Equal(1, len(byCtx.Executions)) + assertion.Equal(*createdEntityId, *byCtx.Executions[0].Id) +} + +func TestCreateServeModelFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + // end of data preparation + + eut := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + ExternalID: &entityExternalId2, + Description: &entityDescription, + Name: &entityName, + ModelVersionId: "9998", + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + _, err := service.UpsertServeModel(eut, nil) + assertion.NotNil(err) + assertion.Equal("missing parentResourceId, cannot create ServeModel without parent resource InferenceService", err.Error()) + + _, err = service.UpsertServeModel(eut, &inferenceServiceId) + assertion.NotNil(err) + assertion.Equal("no model version found for id 9998", err.Error()) +} + +func TestUpdateServeModel(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + Description: &modelVersionDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersionId := *createdVersion.Id + createdVersionIdAsInt, _ := converter.StringToInt64(&createdVersionId) + // end of data preparation + + eut := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + ExternalID: &entityExternalId2, + Description: &entityDescription, + Name: &entityName, + ModelVersionId: createdVersionId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) + assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + + newState := "UNKNOWN" + createdEntity.LastKnownState = (*openapi.ExecutionState)(&newState) + updatedEntity, err := service.UpsertServeModel(createdEntity, &inferenceServiceId) + assertion.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) + + createdEntityId, _ := converter.StringToInt64(createdEntity.Id) + updatedEntityId, _ := converter.StringToInt64(updatedEntity.Id) + assertion.Equal(createdEntityId, updatedEntityId) + + getById, err := client.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ + ExecutionIds: []int64{*createdEntityId}, + }) + assertion.Nilf(err, "error getting by id %d", createdEntityId) + + assertion.Equal(*createdEntityId, *getById.Executions[0].Id) + assertion.Equal(fmt.Sprintf("%s:%s", inferenceServiceId, *createdEntity.Name), *getById.Executions[0].Name) + assertion.Equal(string(newState), getById.Executions[0].LastKnownState.String()) + assertion.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) + assertion.Equal(*(*createdEntity.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["author"].GetStringValue()) +} + +func TestUpdateServeModelFailure(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + Description: &modelVersionDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersionId := *createdVersion.Id + // end of data preparation + + eut := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + ExternalID: &entityExternalId2, + Description: &entityDescription, + Name: &entityName, + ModelVersionId: createdVersionId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) + assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + assertion.NotNil(createdEntity.Id, "created id should not be nil") + + newState := "UNKNOWN" + createdEntity.LastKnownState = (*openapi.ExecutionState)(&newState) + updatedEntity, err := service.UpsertServeModel(createdEntity, &inferenceServiceId) + assertion.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) + + wrongId := "9998" + updatedEntity.Id = &wrongId + _, err = service.UpsertServeModel(updatedEntity, &inferenceServiceId) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("no ServeModel found for id %s", wrongId), err.Error()) +} + +func TestGetServeModelById(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + + modelVersion := &openapi.ModelVersion{ + Name: &modelVersionName, + ExternalID: &versionExternalId, + Description: &modelVersionDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersionId := *createdVersion.Id + // end of data preparation + + eut := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + ExternalID: &entityExternalId2, + Description: &entityDescription, + Name: &entityName, + ModelVersionId: createdVersionId, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) + assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + + getById, err := service.GetServeModelById(*createdEntity.Id) + assertion.Nilf(err, "error getting entity by id %d", *createdEntity.Id) + + state, _ := openapi.NewExecutionStateFromValue(executionState) + assertion.NotNil(createdEntity.Id, "created artifact id should not be nil") + assertion.Equal(entityName, *getById.Name) + assertion.Equal(*state, *getById.LastKnownState) + assertion.Equal(createdVersionId, getById.ModelVersionId) + assertion.Equal(author, *(*getById.CustomProperties)["author"].MetadataStringValue.StringValue) + + assertion.Equal(*createdEntity, *getById, "artifacts returned during creation and on get by id should be equal") +} + +func TestGetServeModels(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + + modelVersion1Name := "v1" + modelVersion1 := &openapi.ModelVersion{Name: &modelVersion1Name, Description: &modelVersionDescription} + createdVersion1, err := service.UpsertModelVersion(modelVersion1, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersion1Id := *createdVersion1.Id + + modelVersion2Name := "v2" + modelVersion2 := &openapi.ModelVersion{Name: &modelVersion2Name, Description: &modelVersionDescription} + createdVersion2, err := service.UpsertModelVersion(modelVersion2, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersion2Id := *createdVersion2.Id + + modelVersion3Name := "v3" + modelVersion3 := &openapi.ModelVersion{Name: &modelVersion3Name, Description: &modelVersionDescription} + createdVersion3, err := service.UpsertModelVersion(modelVersion3, ®isteredModelId) + assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + createdVersion3Id := *createdVersion3.Id + // end of data preparation + + eut1Name := "sm1" + eut1 := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + Description: &entityDescription, + Name: &eut1Name, + ModelVersionId: createdVersion1Id, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + eut2Name := "sm2" + eut2 := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + Description: &entityDescription, + Name: &eut2Name, + ModelVersionId: createdVersion2Id, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + eut3Name := "sm3" + eut3 := &openapi.ServeModel{ + LastKnownState: (*openapi.ExecutionState)(&executionState), + Description: &entityDescription, + Name: &eut3Name, + ModelVersionId: createdVersion3Id, + CustomProperties: &map[string]openapi.MetadataValue{ + "author": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &author, + }, + }, + }, + } + + createdEntity1, err := service.UpsertServeModel(eut1, &inferenceServiceId) + assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + createdEntity2, err := service.UpsertServeModel(eut2, &inferenceServiceId) + assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + createdEntity3, err := service.UpsertServeModel(eut3, &inferenceServiceId) + assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + + createdEntityId1, _ := converter.StringToInt64(createdEntity1.Id) + createdEntityId2, _ := converter.StringToInt64(createdEntity2.Id) + createdEntityId3, _ := converter.StringToInt64(createdEntity3.Id) + + getAll, err := service.GetServeModels(ListOptions{}, nil) + assertion.Nilf(err, "error getting all ServeModel") + assertion.Equalf(int32(3), getAll.Size, "expected three ServeModel") + + assertion.Equal(*converter.Int64ToString(createdEntityId1), *getAll.Items[0].Id) + assertion.Equal(*converter.Int64ToString(createdEntityId2), *getAll.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdEntityId3), *getAll.Items[2].Id) + + orderByLastUpdate := "LAST_UPDATE_TIME" + getAllByInferenceService, err := service.GetServeModels(ListOptions{ + OrderBy: &orderByLastUpdate, + SortOrder: &descOrderDirection, + }, &inferenceServiceId) + assertion.Nilf(err, "error getting all ServeModels for %d", inferenceServiceId) + assertion.Equalf(int32(3), getAllByInferenceService.Size, "expected three ServeModels for InferenceServiceId %d", inferenceServiceId) + + assertion.Equal(*converter.Int64ToString(createdEntityId1), *getAllByInferenceService.Items[2].Id) + assertion.Equal(*converter.Int64ToString(createdEntityId2), *getAllByInferenceService.Items[1].Id) + assertion.Equal(*converter.Int64ToString(createdEntityId3), *getAllByInferenceService.Items[0].Id) +} diff --git a/internal/core/mapper.go b/internal/core/mapper.go index faed2eb1..d68b3dd5 100644 --- a/internal/core/mapper.go +++ b/internal/core/mapper.go @@ -10,20 +10,26 @@ import ( ) type Mapper struct { - OpenAPIConverter converter.OpenAPIToMLMDConverter - MLMDConverter converter.MLMDToOpenAPIConverter - RegisteredModelTypeId int64 - ModelVersionTypeId int64 - ModelArtifactTypeId int64 + OpenAPIConverter converter.OpenAPIToMLMDConverter + MLMDConverter converter.MLMDToOpenAPIConverter + RegisteredModelTypeId int64 + ModelVersionTypeId int64 + ModelArtifactTypeId int64 + ServingEnvironmentTypeId int64 + InferenceServiceTypeId int64 + ServeModelTypeId int64 } -func NewMapper(registeredModelTypeId int64, modelVersionTypeId int64, modelArtifactTypeId int64) *Mapper { +func NewMapper(registeredModelTypeId int64, modelVersionTypeId int64, modelArtifactTypeId int64, servingEnvironmentTypeId int64, inferenceServiceTypeId int64, serveModelTypeId int64) *Mapper { return &Mapper{ - OpenAPIConverter: &generated.OpenAPIToMLMDConverterImpl{}, - MLMDConverter: &generated.MLMDToOpenAPIConverterImpl{}, - RegisteredModelTypeId: registeredModelTypeId, - ModelVersionTypeId: modelVersionTypeId, - ModelArtifactTypeId: modelArtifactTypeId, + OpenAPIConverter: &generated.OpenAPIToMLMDConverterImpl{}, + MLMDConverter: &generated.MLMDToOpenAPIConverterImpl{}, + RegisteredModelTypeId: registeredModelTypeId, + ModelVersionTypeId: modelVersionTypeId, + ModelArtifactTypeId: modelArtifactTypeId, + ServingEnvironmentTypeId: servingEnvironmentTypeId, + InferenceServiceTypeId: inferenceServiceTypeId, + ServeModelTypeId: serveModelTypeId, } } @@ -84,6 +90,44 @@ func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact, return artifacts, nil } +func (m *Mapper) MapFromServingEnvironment(servingEnvironment *openapi.ServingEnvironment) (*proto.Context, error) { + ctx, err := m.OpenAPIConverter.ConvertServingEnvironment(&converter.OpenAPIModelWrapper[openapi.ServingEnvironment]{ + TypeId: m.ServingEnvironmentTypeId, + Model: servingEnvironment, + }) + if err != nil { + return nil, err + } + + return ctx, nil +} + +func (m *Mapper) MapFromInferenceService(inferenceService *openapi.InferenceService, servingEnvironmentId string, servingEnvironmentName *string) (*proto.Context, error) { + ctx, err := m.OpenAPIConverter.ConvertInferenceService(&converter.OpenAPIModelWrapper[openapi.InferenceService]{ + TypeId: m.InferenceServiceTypeId, + Model: inferenceService, + ParentResourceId: &servingEnvironmentId, + }) + if err != nil { + return nil, err + } + + return ctx, nil +} + +func (m *Mapper) MapFromServeModel(serveModel *openapi.ServeModel, inferenceServiceId string) (*proto.Execution, error) { + ctx, err := m.OpenAPIConverter.ConvertServeModel(&converter.OpenAPIModelWrapper[openapi.ServeModel]{ + TypeId: m.ServeModelTypeId, + Model: serveModel, + ParentResourceId: &inferenceServiceId, + }) + if err != nil { + return nil, err + } + + return ctx, nil +} + // Utilities for MLMD --> OpenAPI mapping, make use of generated Converters func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredModel, error) { @@ -109,3 +153,26 @@ func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArt return m.MLMDConverter.ConvertModelArtifact(artifact) } + +func (m *Mapper) MapToServingEnvironment(ctx *proto.Context) (*openapi.ServingEnvironment, error) { + return mapTo(ctx, m.ServingEnvironmentTypeId, m.MLMDConverter.ConvertServingEnvironment) +} + +func (m *Mapper) MapToInferenceService(ctx *proto.Context) (*openapi.InferenceService, error) { + return mapTo(ctx, m.InferenceServiceTypeId, m.MLMDConverter.ConvertInferenceService) +} + +func (m *Mapper) MapToServeModel(ctx *proto.Execution) (*openapi.ServeModel, error) { + return mapTo(ctx, m.ServeModelTypeId, m.MLMDConverter.ConvertServeModel) +} + +type getTypeIder interface { + GetTypeId() int64 +} + +func mapTo[S getTypeIder, T any](s S, id int64, convFn func(S) (*T, error)) (*T, error) { + if s.GetTypeId() != id { + return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", id, s.GetTypeId()) + } + return convFn(s) +} diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index 78cad7c1..7369dad5 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -38,88 +38,58 @@ func NewModelRegistryServiceAPIService(coreApi core.ModelRegistryApi) ModelRegis // CreateEnvironmentInferenceService - Create a InferenceService in ServingEnvironment func (s *ModelRegistryServiceAPIService) CreateEnvironmentInferenceService(ctx context.Context, servingenvironmentId string, inferenceServiceCreate model.InferenceServiceCreate) (ImplResponse, error) { - // TODO - update CreateEnvironmentInferenceService with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(201, InferenceService{}) or use other options such as http.Ok ... - // return Response(201, InferenceService{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("CreateEnvironmentInferenceService method not implemented") + inferenceServiceCreate.ServingEnvironmentId = servingenvironmentId + return s.CreateInferenceService(ctx, inferenceServiceCreate) + // TODO: return Response(404, Error{}), nil } // CreateInferenceService - Create a InferenceService func (s *ModelRegistryServiceAPIService) CreateInferenceService(ctx context.Context, inferenceServiceCreate model.InferenceServiceCreate) (ImplResponse, error) { - // TODO - update CreateInferenceService with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... - // return Response(200, InferenceService{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil + entity, err := s.converter.ConvertInferenceServiceCreate(&inferenceServiceCreate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } - return Response(http.StatusNotImplemented, nil), errors.New("CreateInferenceService method not implemented") + result, err := s.coreApi.UpsertInferenceService(entity) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(201, result), nil + // TODO: return Response(400, Error{}), nil + // TODO: return Response(401, Error{}), nil } // CreateInferenceServiceServe - Create a ServeModel action in a InferenceService func (s *ModelRegistryServiceAPIService) CreateInferenceServiceServe(ctx context.Context, inferenceserviceId string, serveModelCreate model.ServeModelCreate) (ImplResponse, error) { - // TODO - update CreateInferenceServiceServe with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(201, ServeModel{}) or use other options such as http.Ok ... - // return Response(201, ServeModel{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil + entity, err := s.converter.ConvertServeModelCreate(&serveModelCreate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } - return Response(http.StatusNotImplemented, nil), errors.New("CreateInferenceServiceServe method not implemented") + result, err := s.coreApi.UpsertServeModel(entity, &inferenceserviceId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(201, result), nil + // TODO: return Response(400, Error{}), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // CreateModelArtifact - Create a ModelArtifact func (s *ModelRegistryServiceAPIService) CreateModelArtifact(ctx context.Context, modelArtifactCreate model.ModelArtifactCreate) (ImplResponse, error) { - // TODO - update CreateModelArtifact with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(201, ModelArtifact{}) or use other options such as http.Ok ... - // return Response(201, ModelArtifact{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil + entity, err := s.converter.ConvertModelArtifactCreate(&modelArtifactCreate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } - return Response(http.StatusNotImplemented, nil), errors.New("CreateModelArtifact method not implemented") + result, err := s.coreApi.UpsertModelArtifact(entity, nil) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(201, result), nil + // TODO: return Response(400, Error{}), nil + // TODO: return Response(401, Error{}), nil } // CreateModelVersion - Create a ModelVersion @@ -158,7 +128,6 @@ func (s *ModelRegistryServiceAPIService) CreateModelVersionArtifact(ctx context. // CreateRegisteredModel - Create a RegisteredModel func (s *ModelRegistryServiceAPIService) CreateRegisteredModel(ctx context.Context, registeredModelCreate model.RegisteredModelCreate) (ImplResponse, error) { - registeredModel, err := s.converter.ConvertRegisteredModelCreate(®isteredModelCreate) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil @@ -187,45 +156,30 @@ func (s *ModelRegistryServiceAPIService) CreateRegisteredModelVersion(ctx contex // CreateServingEnvironment - Create a ServingEnvironment func (s *ModelRegistryServiceAPIService) CreateServingEnvironment(ctx context.Context, servingEnvironmentCreate model.ServingEnvironmentCreate) (ImplResponse, error) { - // TODO - update CreateServingEnvironment with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(201, ServingEnvironment{}) or use other options such as http.Ok ... - // return Response(201, ServingEnvironment{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil + entity, err := s.converter.ConvertServingEnvironmentCreate(&servingEnvironmentCreate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } - return Response(http.StatusNotImplemented, nil), errors.New("CreateServingEnvironment method not implemented") + result, err := s.coreApi.UpsertServingEnvironment(entity) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(201, result), nil + // TODO: return Response(400, Error{}), nil + // TODO: return Response(401, Error{}), nil } // FindInferenceService - Get an InferenceServices that matches search parameters. func (s *ModelRegistryServiceAPIService) FindInferenceService(ctx context.Context, name string, externalID string) (ImplResponse, error) { - // TODO - update FindInferenceService with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... - // return Response(200, InferenceService{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("FindInferenceService method not implemented") + result, err := s.coreApi.GetInferenceServiceByParams(&name, nil, &externalID) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return esponse(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // FindModelArtifact - Get a ModelArtifact that matches search parameters. @@ -266,145 +220,112 @@ func (s *ModelRegistryServiceAPIService) FindRegisteredModel(ctx context.Context // FindServingEnvironment - Find ServingEnvironment func (s *ModelRegistryServiceAPIService) FindServingEnvironment(ctx context.Context, name string, externalID string) (ImplResponse, error) { - // TODO - update FindServingEnvironment with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ServingEnvironment{}) or use other options such as http.Ok ... - // return Response(200, ServingEnvironment{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("FindServingEnvironment method not implemented") + result, err := s.coreApi.GetServingEnvironmentByParams(&name, &externalID) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetEnvironmentInferenceServices - List All ServingEnvironment's InferenceServices func (s *ModelRegistryServiceAPIService) GetEnvironmentInferenceServices(ctx context.Context, servingenvironmentId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetEnvironmentInferenceServices with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, InferenceServiceList{}) or use other options such as http.Ok ... - // return Response(200, InferenceServiceList{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetEnvironmentInferenceServices method not implemented") + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetInferenceServices(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }, &servingenvironmentId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetInferenceService - Get a InferenceService func (s *ModelRegistryServiceAPIService) GetInferenceService(ctx context.Context, inferenceserviceId string) (ImplResponse, error) { - // TODO - update GetInferenceService with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... - // return Response(200, InferenceService{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceService method not implemented") + result, err := s.coreApi.GetInferenceServiceById(inferenceserviceId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // GetInferenceServiceModel - Get InferenceService's RegisteredModel func (s *ModelRegistryServiceAPIService) GetInferenceServiceModel(ctx context.Context, inferenceserviceId string) (ImplResponse, error) { - // TODO - update GetInferenceServiceModel with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, RegisteredModel{}) or use other options such as http.Ok ... - // return Response(200, RegisteredModel{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServiceModel method not implemented") + result, err := s.coreApi.GetRegisteredModelByInferenceService(inferenceserviceId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // GetInferenceServiceServes - List All InferenceService's ServeModel actions func (s *ModelRegistryServiceAPIService) GetInferenceServiceServes(ctx context.Context, inferenceserviceId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetInferenceServiceServes with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ServeModelList{}) or use other options such as http.Ok ... - // return Response(200, ServeModelList{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServiceServes method not implemented") + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetServeModels(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }, &inferenceserviceId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetInferenceServiceVersion - Get InferenceService's ModelVersion func (s *ModelRegistryServiceAPIService) GetInferenceServiceVersion(ctx context.Context, inferenceserviceId string) (ImplResponse, error) { - // TODO - update GetInferenceServiceVersion with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ModelVersion{}) or use other options such as http.Ok ... - // return Response(200, ModelVersion{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServiceVersion method not implemented") + result, err := s.coreApi.GetModelVersionByInferenceService(inferenceserviceId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // GetInferenceServices - List All InferenceServices func (s *ModelRegistryServiceAPIService) GetInferenceServices(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetInferenceServices with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, InferenceServiceList{}) or use other options such as http.Ok ... - // return Response(200, InferenceServiceList{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetInferenceServices method not implemented") + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetInferenceServices(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }, nil) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // GetModelArtifact - Get a ModelArtifact @@ -559,62 +480,51 @@ func (s *ModelRegistryServiceAPIService) GetRegisteredModels(ctx context.Context // GetServingEnvironment - Get a ServingEnvironment func (s *ModelRegistryServiceAPIService) GetServingEnvironment(ctx context.Context, servingenvironmentId string) (ImplResponse, error) { - // TODO - update GetServingEnvironment with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ServingEnvironment{}) or use other options such as http.Ok ... - // return Response(200, ServingEnvironment{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetServingEnvironment method not implemented") + result, err := s.coreApi.GetServingEnvironmentById(servingenvironmentId) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO: return Response(401, Error{}), nil + // TODO: return Response(404, Error{}), nil } // GetServingEnvironments - List All ServingEnvironments func (s *ModelRegistryServiceAPIService) GetServingEnvironments(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - // TODO - update GetServingEnvironments with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ServingEnvironmentList{}) or use other options such as http.Ok ... - // return Response(200, ServingEnvironmentList{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("GetServingEnvironments method not implemented") + orderByString := string(orderBy) + sortOrderString := string(sortOrder) + pageSizeInt32, err := converter.StringToInt32(pageSize) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + result, err := s.coreApi.GetServingEnvironments(core.ListOptions{ + PageSize: &pageSizeInt32, + OrderBy: &orderByString, + SortOrder: &sortOrderString, + NextPageToken: &nextPageToken, + }) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(401, Error{}), nil } // UpdateInferenceService - Update a InferenceService func (s *ModelRegistryServiceAPIService) UpdateInferenceService(ctx context.Context, inferenceserviceId string, inferenceServiceUpdate model.InferenceServiceUpdate) (ImplResponse, error) { - // TODO - update UpdateInferenceService with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, InferenceService{}) or use other options such as http.Ok ... - // return Response(200, InferenceService{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("UpdateInferenceService method not implemented") + entity, err := s.converter.ConvertInferenceServiceUpdate(&inferenceServiceUpdate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + entity.Id = &inferenceserviceId + result, err := s.coreApi.UpsertInferenceService(entity) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } // UpdateModelArtifact - Update a ModelArtifact @@ -671,23 +581,17 @@ func (s *ModelRegistryServiceAPIService) UpdateRegisteredModel(ctx context.Conte // UpdateServingEnvironment - Update a ServingEnvironment func (s *ModelRegistryServiceAPIService) UpdateServingEnvironment(ctx context.Context, servingenvironmentId string, servingEnvironmentUpdate model.ServingEnvironmentUpdate) (ImplResponse, error) { - // TODO - update UpdateServingEnvironment with the required logic for this service method. - // Add api_model_registry_service_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. - - // TODO: Uncomment the next line to return response Response(200, ServingEnvironment{}) or use other options such as http.Ok ... - // return Response(200, ServingEnvironment{}), nil - - // TODO: Uncomment the next line to return response Response(400, Error{}) or use other options such as http.Ok ... - // return Response(400, Error{}), nil - - // TODO: Uncomment the next line to return response Response(401, Error{}) or use other options such as http.Ok ... - // return Response(401, Error{}), nil - - // TODO: Uncomment the next line to return response Response(404, Error{}) or use other options such as http.Ok ... - // return Response(404, Error{}), nil - - // TODO: Uncomment the next line to return response Response(500, Error{}) or use other options such as http.Ok ... - // return Response(500, Error{}), nil - - return Response(http.StatusNotImplemented, nil), errors.New("UpdateServingEnvironment method not implemented") + entity, err := s.converter.ConvertServingEnvironmentUpdate(&servingEnvironmentUpdate) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + entity.Id = &servingenvironmentId + result, err := s.coreApi.UpsertServingEnvironment(entity) + if err != nil { + return Response(500, model.Error{Message: err.Error()}), nil + } + return Response(200, result), nil + // TODO return Response(400, Error{}), nil + // TODO return Response(401, Error{}), nil + // TODO return Response(404, Error{}), nil } diff --git a/internal/testutils/test_container_utils.go b/internal/testutils/test_container_utils.go index 441bfd01..aa5c1b53 100644 --- a/internal/testutils/test_container_utils.go +++ b/internal/testutils/test_container_utils.go @@ -2,6 +2,7 @@ package testutils import ( "context" + "errors" "fmt" "os" "testing" @@ -27,6 +28,17 @@ func clearMetadataSqliteDB(wd string) error { return nil } +func fileExists(filePath string) (bool, error) { + info, err := os.Stat(filePath) + if err == nil { + return !info.IsDir(), nil + } + if errors.Is(err, os.ErrNotExist) { + return false, nil + } + return false, err +} + // SetupMLMDTestContainer creates a MLMD gRPC test container // Returns // - gRPC client connection to the test container @@ -41,6 +53,18 @@ func SetupMLMDTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStore wd = fmt.Sprintf("%s/../../%s", wd, testConfigFolder) t.Logf("using working directory: %s", wd) + // when unhandled panics or other hard failures, could leave the DB in the directory + // here we make sure it's not existing already, and that it was really cleanup by previous runs + sqlitePath := fmt.Sprintf("%s/%s", wd, sqliteFile) + exists, err := fileExists(sqlitePath) + if err != nil { + t.Errorf("error looking up for SQLite path: %v", err) + } + if exists { + t.Errorf("SQLite should not exists: %v", sqlitePath) + panic("halting immediately, SQLite should not exists: " + sqlitePath) + } + req := testcontainers.ContainerRequest{ Image: mlmdImage, ExposedPorts: []string{"8080/tcp"}, From 571bc6ba008c85cad8c0be6f671363314d72653e Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Fri, 10 Nov 2023 10:39:33 +0100 Subject: [PATCH 114/254] Move runtime from Artifact to InferenceService (#134) --- api/openapi/model-registry.yaml | 6 +- .../generated/mlmd_openapi_converter.gen.go | 2 +- .../generated/openapi_converter.gen.go | 72 +++++++++---------- .../converter/mlmd_converter_util_test.go | 12 ++-- internal/converter/mlmd_openapi_converter.go | 2 +- .../converter/mlmd_openapi_converter_util.go | 10 +-- .../converter/openapi_mlmd_converter_util.go | 15 ++-- internal/core/core.go | 2 +- .../model/openapi/model_inference_service.go | 37 ++++++++++ .../openapi/model_inference_service_create.go | 37 ++++++++++ .../openapi/model_inference_service_update.go | 37 ++++++++++ .../model/openapi/model_model_artifact.go | 37 ---------- .../openapi/model_model_artifact_create.go | 37 ---------- .../openapi/model_model_artifact_update.go | 37 ---------- 14 files changed, 173 insertions(+), 170 deletions(-) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index 511b237b..0f3e2277 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -1329,9 +1329,6 @@ components: modelFormatName: description: Name of the model format. type: string - runtime: - description: Model runtime. - type: string storageKey: description: Storage secret name. type: string @@ -1534,6 +1531,9 @@ components: ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. type: string + runtime: + description: Model runtime. + type: string InferenceServiceCreate: description: >- An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index aaaa04f4..403734d5 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -32,6 +32,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertInferenceService(source *proto.Conte openapiInferenceService.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) openapiInferenceService.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) openapiInferenceService.ModelVersionId = converter.MapPropertyModelVersionId((*source).Properties) + openapiInferenceService.Runtime = converter.MapPropertyRuntime((*source).Properties) openapiInferenceService.RegisteredModelId = converter.MapPropertyRegisteredModelId((*source).Properties) openapiInferenceService.ServingEnvironmentId = converter.MapPropertyServingEnvironmentId((*source).Properties) pOpenapiInferenceService = &openapiInferenceService @@ -71,7 +72,6 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertModelArtifact(source *proto.Artifact } openapiModelArtifact.ArtifactType = xstring3 openapiModelArtifact.ModelFormatName = converter.MapModelArtifactFormatName((*source).Properties) - openapiModelArtifact.Runtime = converter.MapModelArtifactRuntime((*source).Properties) openapiModelArtifact.StorageKey = converter.MapModelArtifactStorageKey((*source).Properties) openapiModelArtifact.StoragePath = converter.MapModelArtifactStoragePath((*source).Properties) openapiModelArtifact.ModelFormatVersion = converter.MapModelArtifactFormatVersion((*source).Properties) diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index e9927185..a27563b7 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -43,6 +43,12 @@ func (c *OpenAPIConverterImpl) ConvertInferenceServiceCreate(source *openapi.Inf pString4 = &xstring4 } openapiInferenceService.ModelVersionId = pString4 + var pString5 *string + if (*source).Runtime != nil { + xstring5 := *(*source).Runtime + pString5 = &xstring5 + } + openapiInferenceService.Runtime = pString5 openapiInferenceService.RegisteredModelId = (*source).RegisteredModelId openapiInferenceService.ServingEnvironmentId = (*source).ServingEnvironmentId pOpenapiInferenceService = &openapiInferenceService @@ -80,6 +86,12 @@ func (c *OpenAPIConverterImpl) ConvertInferenceServiceUpdate(source *openapi.Inf pString3 = &xstring3 } openapiInferenceService.ModelVersionId = pString3 + var pString4 *string + if (*source).Runtime != nil { + xstring4 := *(*source).Runtime + pString4 = &xstring4 + } + openapiInferenceService.Runtime = pString4 pOpenapiInferenceService = &openapiInferenceService } return pOpenapiInferenceService, nil @@ -134,35 +146,29 @@ func (c *OpenAPIConverterImpl) ConvertModelArtifactCreate(source *openapi.ModelA } openapiModelArtifact.ModelFormatName = pString5 var pString6 *string - if (*source).Runtime != nil { - xstring6 := *(*source).Runtime + if (*source).StorageKey != nil { + xstring6 := *(*source).StorageKey pString6 = &xstring6 } - openapiModelArtifact.Runtime = pString6 + openapiModelArtifact.StorageKey = pString6 var pString7 *string - if (*source).StorageKey != nil { - xstring7 := *(*source).StorageKey + if (*source).StoragePath != nil { + xstring7 := *(*source).StoragePath pString7 = &xstring7 } - openapiModelArtifact.StorageKey = pString7 + openapiModelArtifact.StoragePath = pString7 var pString8 *string - if (*source).StoragePath != nil { - xstring8 := *(*source).StoragePath + if (*source).ModelFormatVersion != nil { + xstring8 := *(*source).ModelFormatVersion pString8 = &xstring8 } - openapiModelArtifact.StoragePath = pString8 + openapiModelArtifact.ModelFormatVersion = pString8 var pString9 *string - if (*source).ModelFormatVersion != nil { - xstring9 := *(*source).ModelFormatVersion - pString9 = &xstring9 - } - openapiModelArtifact.ModelFormatVersion = pString9 - var pString10 *string if (*source).ServiceAccountName != nil { - xstring10 := *(*source).ServiceAccountName - pString10 = &xstring10 + xstring9 := *(*source).ServiceAccountName + pString9 = &xstring9 } - openapiModelArtifact.ServiceAccountName = pString10 + openapiModelArtifact.ServiceAccountName = pString9 pOpenapiModelArtifact = &openapiModelArtifact } return pOpenapiModelArtifact, nil @@ -211,35 +217,29 @@ func (c *OpenAPIConverterImpl) ConvertModelArtifactUpdate(source *openapi.ModelA } openapiModelArtifact.ModelFormatName = pString4 var pString5 *string - if (*source).Runtime != nil { - xstring5 := *(*source).Runtime + if (*source).StorageKey != nil { + xstring5 := *(*source).StorageKey pString5 = &xstring5 } - openapiModelArtifact.Runtime = pString5 + openapiModelArtifact.StorageKey = pString5 var pString6 *string - if (*source).StorageKey != nil { - xstring6 := *(*source).StorageKey + if (*source).StoragePath != nil { + xstring6 := *(*source).StoragePath pString6 = &xstring6 } - openapiModelArtifact.StorageKey = pString6 + openapiModelArtifact.StoragePath = pString6 var pString7 *string - if (*source).StoragePath != nil { - xstring7 := *(*source).StoragePath + if (*source).ModelFormatVersion != nil { + xstring7 := *(*source).ModelFormatVersion pString7 = &xstring7 } - openapiModelArtifact.StoragePath = pString7 + openapiModelArtifact.ModelFormatVersion = pString7 var pString8 *string - if (*source).ModelFormatVersion != nil { - xstring8 := *(*source).ModelFormatVersion - pString8 = &xstring8 - } - openapiModelArtifact.ModelFormatVersion = pString8 - var pString9 *string if (*source).ServiceAccountName != nil { - xstring9 := *(*source).ServiceAccountName - pString9 = &xstring9 + xstring8 := *(*source).ServiceAccountName + pString8 = &xstring8 } - openapiModelArtifact.ServiceAccountName = pString9 + openapiModelArtifact.ServiceAccountName = pString8 pOpenapiModelArtifact = &openapiModelArtifact } return pOpenapiModelArtifact, nil diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index 1d898601..797ce96d 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -232,16 +232,14 @@ func TestMapModelArtifactProperties(t *testing.T) { Name: of("v1"), ModelFormatName: of("sklearn"), ModelFormatVersion: of("1.0"), - Runtime: of("my-runtime"), StorageKey: of("storage-key"), StoragePath: of("storage-path"), ServiceAccountName: of("service-account-name"), }) assertion.Nil(err) - assertion.Equal(6, len(props)) + assertion.Equal(5, len(props)) assertion.Equal("sklearn", props["model_format_name"].GetStringValue()) assertion.Equal("1.0", props["model_format_version"].GetStringValue()) - assertion.Equal("my-runtime", props["runtime"].GetStringValue()) assertion.Equal("storage-key", props["storage_key"].GetStringValue()) assertion.Equal("storage-path", props["storage_path"].GetStringValue()) assertion.Equal("service-account-name", props["service_account_name"].GetStringValue()) @@ -329,10 +327,10 @@ func TestMapDescription(t *testing.T) { assertion.Equal("my-description", *extracted) } -func TestMapModelArtifactRuntime(t *testing.T) { +func TestPropertyRuntime(t *testing.T) { assertion := setup(t) - extracted := MapModelArtifactRuntime(map[string]*proto.Value{ + extracted := MapPropertyRuntime(map[string]*proto.Value{ "runtime": { Value: &proto.Value_StringValue{ StringValue: "my-runtime", @@ -478,13 +476,15 @@ func TestMapInferenceServiceProperties(t *testing.T) { props, err := MapInferenceServiceProperties(&openapi.InferenceService{ Description: of("my custom description"), ModelVersionId: of("1"), + Runtime: of("my-runtime"), RegisteredModelId: "2", ServingEnvironmentId: "3", }) assertion.Nil(err) - assertion.Equal(4, len(props)) + assertion.Equal(5, len(props)) assertion.Equal("my custom description", props["description"].GetStringValue()) assertion.Equal(int64(1), props["model_version_id"].GetIntValue()) + assertion.Equal("my-runtime", props["runtime"].GetStringValue()) assertion.Equal(int64(2), props["registered_model_id"].GetIntValue()) assertion.Equal(int64(3), props["serving_environment_id"].GetIntValue()) diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index 358e3da3..fb3d2125 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -25,7 +25,6 @@ type MLMDToOpenAPIConverter interface { // goverter:map . ArtifactType | MapArtifactType // goverter:map State | MapMLMDModelArtifactState // goverter:map Properties Description | MapDescription - // goverter:map Properties Runtime | MapModelArtifactRuntime // goverter:map Properties ModelFormatName | MapModelArtifactFormatName // goverter:map Properties ModelFormatVersion | MapModelArtifactFormatVersion // goverter:map Properties StorageKey | MapModelArtifactStorageKey @@ -39,6 +38,7 @@ type MLMDToOpenAPIConverter interface { // goverter:map Name | MapNameFromOwned // goverter:map Properties Description | MapDescription + // goverter:map Properties Runtime | MapPropertyRuntime // goverter:map Properties ModelVersionId | MapPropertyModelVersionId // goverter:map Properties RegisteredModelId | MapPropertyRegisteredModelId // goverter:map Properties ServingEnvironmentId | MapPropertyServingEnvironmentId diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 5a2092be..634382be 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -130,10 +130,6 @@ func MapDescription(properties map[string]*proto.Value) *string { return MapStringProperty(properties, "description") } -func MapModelArtifactRuntime(properties map[string]*proto.Value) *string { - return MapStringProperty(properties, "runtime") -} - func MapModelArtifactFormatName(properties map[string]*proto.Value) *string { return MapStringProperty(properties, "model_format_name") } @@ -170,6 +166,12 @@ func MapPropertyServingEnvironmentId(properties map[string]*proto.Value) string return MapIntPropertyAsValue(properties, "serving_environment_id") } +// INFERENCE SERVICE + +func MapPropertyRuntime(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "runtime") +} + // SERVE MODEL func MapMLMDServeModelLastKnownState(source *proto.Execution_State) *openapi.ExecutionState { diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index 6595d834..bd0b886e 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -197,13 +197,6 @@ func MapModelArtifactProperties(source *openapi.ModelArtifact) (map[string]*prot }, } } - if source.Runtime != nil { - props["runtime"] = &proto.Value{ - Value: &proto.Value_StringValue{ - StringValue: *source.Runtime, - }, - } - } if source.ModelFormatName != nil { props["model_format_name"] = &proto.Value{ Value: &proto.Value_StringValue{ @@ -316,6 +309,14 @@ func MapInferenceServiceProperties(source *openapi.InferenceService) (map[string } } + if source.Runtime != nil { + props["runtime"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Runtime, + }, + } + } + registeredModelId, err := StringToInt64(&source.RegisteredModelId) if err != nil { return nil, err diff --git a/internal/core/core.go b/internal/core/core.go index d24913d0..19dc01ae 100644 --- a/internal/core/core.go +++ b/internal/core/core.go @@ -59,7 +59,6 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err Name: modelArtifactTypeName, Properties: map[string]proto.PropertyType{ "description": proto.PropertyType_STRING, - "runtime": proto.PropertyType_STRING, "model_format_name": proto.PropertyType_STRING, "model_format_version": proto.PropertyType_STRING, "storage_key": proto.PropertyType_STRING, @@ -100,6 +99,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err // TODO: check with Andrea, my understanding is parent/child is only for ownership of InferenceService/ServeModel via MLMD Association (Execution ServeModel --> Context InferenceService) // we could remove this as we will use ParentContext to keep track of this association "model_version_id": proto.PropertyType_INT, + "runtime": proto.PropertyType_STRING, }, }, } diff --git a/internal/model/openapi/model_inference_service.go b/internal/model/openapi/model_inference_service.go index 555197b2..9aa49ab1 100644 --- a/internal/model/openapi/model_inference_service.go +++ b/internal/model/openapi/model_inference_service.go @@ -35,6 +35,8 @@ type InferenceService struct { LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` + // Model runtime. + Runtime *string `json:"runtime,omitempty"` // ID of the `RegisteredModel` to serve. RegisteredModelId string `json:"registeredModelId"` // ID of the parent `ServingEnvironment` for this `InferenceService` entity. @@ -316,6 +318,38 @@ func (o *InferenceService) SetModelVersionId(v string) { o.ModelVersionId = &v } +// GetRuntime returns the Runtime field value if set, zero value otherwise. +func (o *InferenceService) GetRuntime() string { + if o == nil || IsNil(o.Runtime) { + var ret string + return ret + } + return *o.Runtime +} + +// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetRuntimeOk() (*string, bool) { + if o == nil || IsNil(o.Runtime) { + return nil, false + } + return o.Runtime, true +} + +// HasRuntime returns a boolean if a field has been set. +func (o *InferenceService) HasRuntime() bool { + if o != nil && !IsNil(o.Runtime) { + return true + } + + return false +} + +// SetRuntime gets a reference to the given string and assigns it to the Runtime field. +func (o *InferenceService) SetRuntime(v string) { + o.Runtime = &v +} + // GetRegisteredModelId returns the RegisteredModelId field value func (o *InferenceService) GetRegisteredModelId() string { if o == nil { @@ -398,6 +432,9 @@ func (o InferenceService) ToMap() (map[string]interface{}, error) { if !IsNil(o.ModelVersionId) { toSerialize["modelVersionId"] = o.ModelVersionId } + if !IsNil(o.Runtime) { + toSerialize["runtime"] = o.Runtime + } toSerialize["registeredModelId"] = o.RegisteredModelId toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId return toSerialize, nil diff --git a/internal/model/openapi/model_inference_service_create.go b/internal/model/openapi/model_inference_service_create.go index b930ca31..178f1189 100644 --- a/internal/model/openapi/model_inference_service_create.go +++ b/internal/model/openapi/model_inference_service_create.go @@ -29,6 +29,8 @@ type InferenceServiceCreate struct { Name *string `json:"name,omitempty"` // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` + // Model runtime. + Runtime *string `json:"runtime,omitempty"` // ID of the `RegisteredModel` to serve. RegisteredModelId string `json:"registeredModelId"` // ID of the parent `ServingEnvironment` for this `InferenceService` entity. @@ -214,6 +216,38 @@ func (o *InferenceServiceCreate) SetModelVersionId(v string) { o.ModelVersionId = &v } +// GetRuntime returns the Runtime field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetRuntime() string { + if o == nil || IsNil(o.Runtime) { + var ret string + return ret + } + return *o.Runtime +} + +// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetRuntimeOk() (*string, bool) { + if o == nil || IsNil(o.Runtime) { + return nil, false + } + return o.Runtime, true +} + +// HasRuntime returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasRuntime() bool { + if o != nil && !IsNil(o.Runtime) { + return true + } + + return false +} + +// SetRuntime gets a reference to the given string and assigns it to the Runtime field. +func (o *InferenceServiceCreate) SetRuntime(v string) { + o.Runtime = &v +} + // GetRegisteredModelId returns the RegisteredModelId field value func (o *InferenceServiceCreate) GetRegisteredModelId() string { if o == nil { @@ -287,6 +321,9 @@ func (o InferenceServiceCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.ModelVersionId) { toSerialize["modelVersionId"] = o.ModelVersionId } + if !IsNil(o.Runtime) { + toSerialize["runtime"] = o.Runtime + } toSerialize["registeredModelId"] = o.RegisteredModelId toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId return toSerialize, nil diff --git a/internal/model/openapi/model_inference_service_update.go b/internal/model/openapi/model_inference_service_update.go index 08527178..0094cc74 100644 --- a/internal/model/openapi/model_inference_service_update.go +++ b/internal/model/openapi/model_inference_service_update.go @@ -27,6 +27,8 @@ type InferenceServiceUpdate struct { ExternalID *string `json:"externalID,omitempty"` // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` + // Model runtime. + Runtime *string `json:"runtime,omitempty"` } // NewInferenceServiceUpdate instantiates a new InferenceServiceUpdate object @@ -174,6 +176,38 @@ func (o *InferenceServiceUpdate) SetModelVersionId(v string) { o.ModelVersionId = &v } +// GetRuntime returns the Runtime field value if set, zero value otherwise. +func (o *InferenceServiceUpdate) GetRuntime() string { + if o == nil || IsNil(o.Runtime) { + var ret string + return ret + } + return *o.Runtime +} + +// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceUpdate) GetRuntimeOk() (*string, bool) { + if o == nil || IsNil(o.Runtime) { + return nil, false + } + return o.Runtime, true +} + +// HasRuntime returns a boolean if a field has been set. +func (o *InferenceServiceUpdate) HasRuntime() bool { + if o != nil && !IsNil(o.Runtime) { + return true + } + + return false +} + +// SetRuntime gets a reference to the given string and assigns it to the Runtime field. +func (o *InferenceServiceUpdate) SetRuntime(v string) { + o.Runtime = &v +} + func (o InferenceServiceUpdate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -196,6 +230,9 @@ func (o InferenceServiceUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.ModelVersionId) { toSerialize["modelVersionId"] = o.ModelVersionId } + if !IsNil(o.Runtime) { + toSerialize["runtime"] = o.Runtime + } return toSerialize, nil } diff --git a/internal/model/openapi/model_model_artifact.go b/internal/model/openapi/model_model_artifact.go index 640397ee..56d708c9 100644 --- a/internal/model/openapi/model_model_artifact.go +++ b/internal/model/openapi/model_model_artifact.go @@ -39,8 +39,6 @@ type ModelArtifact struct { ArtifactType string `json:"artifactType"` // Name of the model format. ModelFormatName *string `json:"modelFormatName,omitempty"` - // Model runtime. - Runtime *string `json:"runtime,omitempty"` // Storage secret name. StorageKey *string `json:"storageKey,omitempty"` // Path for model in storage provided by `storageKey`. @@ -419,38 +417,6 @@ func (o *ModelArtifact) SetModelFormatName(v string) { o.ModelFormatName = &v } -// GetRuntime returns the Runtime field value if set, zero value otherwise. -func (o *ModelArtifact) GetRuntime() string { - if o == nil || IsNil(o.Runtime) { - var ret string - return ret - } - return *o.Runtime -} - -// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *ModelArtifact) GetRuntimeOk() (*string, bool) { - if o == nil || IsNil(o.Runtime) { - return nil, false - } - return o.Runtime, true -} - -// HasRuntime returns a boolean if a field has been set. -func (o *ModelArtifact) HasRuntime() bool { - if o != nil && !IsNil(o.Runtime) { - return true - } - - return false -} - -// SetRuntime gets a reference to the given string and assigns it to the Runtime field. -func (o *ModelArtifact) SetRuntime(v string) { - o.Runtime = &v -} - // GetStorageKey returns the StorageKey field value if set, zero value otherwise. func (o *ModelArtifact) GetStorageKey() string { if o == nil || IsNil(o.StorageKey) { @@ -620,9 +586,6 @@ func (o ModelArtifact) ToMap() (map[string]interface{}, error) { if !IsNil(o.ModelFormatName) { toSerialize["modelFormatName"] = o.ModelFormatName } - if !IsNil(o.Runtime) { - toSerialize["runtime"] = o.Runtime - } if !IsNil(o.StorageKey) { toSerialize["storageKey"] = o.StorageKey } diff --git a/internal/model/openapi/model_model_artifact_create.go b/internal/model/openapi/model_model_artifact_create.go index 83af5c8b..b01bba78 100644 --- a/internal/model/openapi/model_model_artifact_create.go +++ b/internal/model/openapi/model_model_artifact_create.go @@ -32,8 +32,6 @@ type ModelArtifactCreate struct { Name *string `json:"name,omitempty"` // Name of the model format. ModelFormatName *string `json:"modelFormatName,omitempty"` - // Model runtime. - Runtime *string `json:"runtime,omitempty"` // Storage secret name. StorageKey *string `json:"storageKey,omitempty"` // Path for model in storage provided by `storageKey`. @@ -289,38 +287,6 @@ func (o *ModelArtifactCreate) SetModelFormatName(v string) { o.ModelFormatName = &v } -// GetRuntime returns the Runtime field value if set, zero value otherwise. -func (o *ModelArtifactCreate) GetRuntime() string { - if o == nil || IsNil(o.Runtime) { - var ret string - return ret - } - return *o.Runtime -} - -// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *ModelArtifactCreate) GetRuntimeOk() (*string, bool) { - if o == nil || IsNil(o.Runtime) { - return nil, false - } - return o.Runtime, true -} - -// HasRuntime returns a boolean if a field has been set. -func (o *ModelArtifactCreate) HasRuntime() bool { - if o != nil && !IsNil(o.Runtime) { - return true - } - - return false -} - -// SetRuntime gets a reference to the given string and assigns it to the Runtime field. -func (o *ModelArtifactCreate) SetRuntime(v string) { - o.Runtime = &v -} - // GetStorageKey returns the StorageKey field value if set, zero value otherwise. func (o *ModelArtifactCreate) GetStorageKey() string { if o == nil || IsNil(o.StorageKey) { @@ -480,9 +446,6 @@ func (o ModelArtifactCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.ModelFormatName) { toSerialize["modelFormatName"] = o.ModelFormatName } - if !IsNil(o.Runtime) { - toSerialize["runtime"] = o.Runtime - } if !IsNil(o.StorageKey) { toSerialize["storageKey"] = o.StorageKey } diff --git a/internal/model/openapi/model_model_artifact_update.go b/internal/model/openapi/model_model_artifact_update.go index 979285ed..e114c5f0 100644 --- a/internal/model/openapi/model_model_artifact_update.go +++ b/internal/model/openapi/model_model_artifact_update.go @@ -30,8 +30,6 @@ type ModelArtifactUpdate struct { State *ArtifactState `json:"state,omitempty"` // Name of the model format. ModelFormatName *string `json:"modelFormatName,omitempty"` - // Model runtime. - Runtime *string `json:"runtime,omitempty"` // Storage secret name. StorageKey *string `json:"storageKey,omitempty"` // Path for model in storage provided by `storageKey`. @@ -255,38 +253,6 @@ func (o *ModelArtifactUpdate) SetModelFormatName(v string) { o.ModelFormatName = &v } -// GetRuntime returns the Runtime field value if set, zero value otherwise. -func (o *ModelArtifactUpdate) GetRuntime() string { - if o == nil || IsNil(o.Runtime) { - var ret string - return ret - } - return *o.Runtime -} - -// GetRuntimeOk returns a tuple with the Runtime field value if set, nil otherwise -// and a boolean to check if the value has been set. -func (o *ModelArtifactUpdate) GetRuntimeOk() (*string, bool) { - if o == nil || IsNil(o.Runtime) { - return nil, false - } - return o.Runtime, true -} - -// HasRuntime returns a boolean if a field has been set. -func (o *ModelArtifactUpdate) HasRuntime() bool { - if o != nil && !IsNil(o.Runtime) { - return true - } - - return false -} - -// SetRuntime gets a reference to the given string and assigns it to the Runtime field. -func (o *ModelArtifactUpdate) SetRuntime(v string) { - o.Runtime = &v -} - // GetStorageKey returns the StorageKey field value if set, zero value otherwise. func (o *ModelArtifactUpdate) GetStorageKey() string { if o == nil || IsNil(o.StorageKey) { @@ -443,9 +409,6 @@ func (o ModelArtifactUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.ModelFormatName) { toSerialize["modelFormatName"] = o.ModelFormatName } - if !IsNil(o.Runtime) { - toSerialize["runtime"] = o.Runtime - } if !IsNil(o.StorageKey) { toSerialize["storageKey"] = o.StorageKey } From 04aa36605d43a9884b06fb9cd68ce46a14b6b717 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 10 Nov 2023 01:40:40 -0800 Subject: [PATCH 115/254] Change mlmd hostname and port cmdline options to k8s style hyphen case (#136) --- Makefile | 6 +++++- cmd/proxy.go | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 5730733d..b43de570 100644 --- a/Makefile +++ b/Makefile @@ -90,7 +90,7 @@ gen/openapi-server: bin/openapi-generator-cli openapi/validate .PHONY: gen/openapi gen/openapi: bin/openapi-generator-cli openapi/validate internal/model/openapi/client.go -internal/model/openapi/client.go: api/openapi/model-registry.yaml +internal/model/openapi/client.go: bin/openapi-generator-cli api/openapi/model-registry.yaml rm -rf internal/model/openapi openapi-generator-cli generate \ -i api/openapi/model-registry.yaml -g go -o internal/model/openapi --package-name openapi \ @@ -141,6 +141,10 @@ ifeq (, $(shell which ${PROJECT_BIN}/openapi-generator-cli 2> /dev/null)) } endif +.PHONY: clean/deps +clean/deps: + rm -Rf bin/* + .PHONY: deps deps: bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/gqlgen bin/golangci-lint bin/goverter bin/openapi-generator-cli diff --git a/cmd/proxy.go b/cmd/proxy.go index 75bb88c7..348f6a72 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -65,8 +65,8 @@ func init() { proxyCmd.Flags().StringVarP(&cfg.Hostname, "hostname", "n", cfg.Hostname, "Proxy server listen hostname") proxyCmd.Flags().IntVarP(&cfg.Port, "port", "p", cfg.Port, "Proxy server listen port") - proxyCmd.Flags().StringVar(&proxyCfg.MLMDHostname, "mlmdhostname", proxyCfg.MLMDHostname, "MLMD hostname") - proxyCmd.Flags().IntVar(&proxyCfg.MLMDPort, "mlmdport", proxyCfg.MLMDPort, "MLMD port") + proxyCmd.Flags().StringVar(&proxyCfg.MLMDHostname, "mlmd-hostname", proxyCfg.MLMDHostname, "MLMD hostname") + proxyCmd.Flags().IntVar(&proxyCfg.MLMDPort, "mlmd-port", proxyCfg.MLMDPort, "MLMD port") } type ProxyConfig struct { From 6595e84e5c8f342321f97d8cfae63e75997020d3 Mon Sep 17 00:00:00 2001 From: Radim Kubis Date: Mon, 13 Nov 2023 15:07:50 +0100 Subject: [PATCH 116/254] Update(Dockerfile): Use ubi9 images that contains required glibc version by gqlgen (#135) --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 74e49bb6..5c98e25a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the model-registry binary -FROM registry.access.redhat.com/ubi8/go-toolset:1.19 as builder +FROM registry.access.redhat.com/ubi9/go-toolset:1.20 as builder WORKDIR /workspace # Copy the Go Modules manifests @@ -37,7 +37,7 @@ RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 make clean model-registry # Use distroless as minimal base image to package the model-registry binary # Refer to https://github.com/GoogleContainerTools/distroless for more details -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.3 WORKDIR / # copy the metadata library COPY --from=builder /workspace/config ./config From d5fc0681f0f75a481f8b098a190869a5b7990e2b Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 7 Nov 2023 19:11:14 -0300 Subject: [PATCH 117/254] py: remove runtime property from model artifact Ref: #131 Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/types/artifacts.py | 4 ---- clients/python/tests/test_client.py | 1 - clients/python/tests/types/test_artifact_mapping.py | 3 --- 3 files changed, 8 deletions(-) diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index 11c5a097..76358483 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -81,7 +81,6 @@ class ModelArtifact(BaseArtifact, Prefixable): external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. model_format_name (str, optional): Name of the model format. model_format_version (str, optional): Version of the model format. - runtime (str, optional): Runtime of the model. storage_key (str, optional): Storage key of the model. storage_path (str, optional): Storage path of the model. service_account_name (str, optional): Service account name of the model. @@ -90,7 +89,6 @@ class ModelArtifact(BaseArtifact, Prefixable): # TODO: this could be an enum of valid formats model_format_name: Optional[str] = field(kw_only=True, default=None) model_format_version: Optional[str] = field(kw_only=True, default=None) - runtime: Optional[str] = field(kw_only=True, default=None) storage_key: Optional[str] = field(kw_only=True, default=None) storage_path: Optional[str] = field(kw_only=True, default=None) service_account_name: Optional[str] = field(kw_only=True, default=None) @@ -104,7 +102,6 @@ def map(self) -> Artifact: props = { "modelFormatName": self.model_format_name, "modelFormatVersion": self.model_format_version, - "runtime": self.runtime, "storageKey": self.storage_key, "storagePath": self.storage_path, "serviceAccountName": self.service_account_name, @@ -122,7 +119,6 @@ def unmap(cls, mlmd_obj: Artifact) -> ModelArtifact: py_obj.model_format_version = mlmd_obj.properties[ "modelFormatVersion" ].string_value - py_obj.runtime = mlmd_obj.properties["runtime"].string_value py_obj.storage_key = mlmd_obj.properties["storageKey"].string_value py_obj.storage_path = mlmd_obj.properties["storagePath"].string_value py_obj.service_account_name = mlmd_obj.properties[ diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 164fd553..e33871a5 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -37,7 +37,6 @@ def model(store_wrapper: MLMDStore) -> Mapped: "description", "modelFormatName", "modelFormatVersion", - "runtime", "storageKey", "storagePath", "serviceAccountName", diff --git a/clients/python/tests/types/test_artifact_mapping.py b/clients/python/tests/types/test_artifact_mapping.py index a249d411..3de2ac49 100644 --- a/clients/python/tests/types/test_artifact_mapping.py +++ b/clients/python/tests/types/test_artifact_mapping.py @@ -21,7 +21,6 @@ def complete_model() -> Mapped: proto_model.properties["description"].string_value = "test description" proto_model.properties["modelFormatName"].string_value = "test_format" proto_model.properties["modelFormatVersion"].string_value = "test_format_version" - proto_model.properties["runtime"].string_value = "test_runtime" proto_model.properties["storageKey"].string_value = "test_storage_key" proto_model.properties["storagePath"].string_value = "test_storage_path" proto_model.properties["serviceAccountName"].string_value = "test_account_name" @@ -33,7 +32,6 @@ def complete_model() -> Mapped: external_id="test_external_id", model_format_name="test_format", model_format_version="test_format_version", - runtime="test_runtime", storage_key="test_storage_key", storage_path="test_storage_path", service_account_name="test_account_name", @@ -93,7 +91,6 @@ def test_full_model_unmapping(complete_model: Mapped): assert unmapped_model.description == py_model.description assert unmapped_model.model_format_name == py_model.model_format_name assert unmapped_model.model_format_version == py_model.model_format_version - assert unmapped_model.runtime == py_model.runtime assert unmapped_model.storage_key == py_model.storage_key assert unmapped_model.storage_path == py_model.storage_path assert unmapped_model.service_account_name == py_model.service_account_name From acec96c922f18ff4e3a661bab4af2fc1b0510f18 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 7 Nov 2023 19:11:14 -0300 Subject: [PATCH 118/254] py: reinsert model on get_mv_by_params Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/client.py | 2 +- clients/python/tests/test_client.py | 28 ++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index fd4b1888..949df75f 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -288,7 +288,7 @@ def get_model_version_by_params( ) py_mv = self._unmap(proto_mv) assert isinstance(py_mv, ModelVersion), "Expected a model version" - # TODO: reinsert model + py_mv.model = self.get_model_artifact_by_params(model_version_id=py_mv.id) return py_mv def upsert_model_artifact( diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index e33871a5..d2c5575d 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -241,12 +241,20 @@ def test_get_model_version_by_id( def test_get_model_version_by_name( - model_registry: ModelRegistry, model_version: Mapped + model_registry: ModelRegistry, model_version: Mapped, model: Mapped ): + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + model_version.proto.name = f"1:{model_version.proto.name}" - id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - id = str(id) + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + ) + + id = str(mv_id) mlmd_mv = model_registry.get_model_version_by_params( registered_model_id="1", version=model_version.py.name @@ -257,14 +265,22 @@ def test_get_model_version_by_name( def test_get_model_version_by_external_id( - model_registry: ModelRegistry, model_version: Mapped + model_registry: ModelRegistry, model_version: Mapped, model: Mapped ): + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + model_version.proto.name = f"1:{model_version.proto.name}" model_version.proto.external_id = "external_id" model_version.py.external_id = "external_id" - id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - id = str(id) + mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_registry._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + ) + + id = str(mv_id) mlmd_mv = model_registry.get_model_version_by_params( external_id=model_version.py.external_id From 04d6a4bd28f820818de36a7a049c8573488cce4e Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 7 Nov 2023 19:11:14 -0300 Subject: [PATCH 119/254] py: client: fix typing issues Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/client.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 949df75f..b68c439d 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -150,7 +150,9 @@ def get_registered_model_by_params( py_rm = self._unmap(proto_rm) assert isinstance(py_rm, RegisteredModel), "Expected a registered model" assert py_rm.id is not None - py_rm.versions = self.get_model_versions(py_rm.id) + versions = self.get_model_versions(py_rm.id) + assert isinstance(versions, list), "Expected a list" + py_rm.versions = versions return py_rm def get_registered_models( @@ -293,7 +295,7 @@ def get_model_version_by_params( def upsert_model_artifact( self, model_artifact: ModelArtifact, model_version_id: str - ) -> None: + ) -> str: """Upsert a model artifact. Updates or creates a model artifact on the server. @@ -323,6 +325,7 @@ def upsert_model_artifact( new_py_ma = self._unmap( self._store.get_artifact(ModelArtifact.get_proto_type_name(), id) ) + assert isinstance(new_py_ma, ModelArtifact), "Expected a model artifact" id = str(id) model_artifact.id = id model_artifact.create_time_since_epoch = new_py_ma.create_time_since_epoch From b31473e7d64e3b2ee64d9b562de4a4b7d9bdae64 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 7 Nov 2023 19:11:15 -0300 Subject: [PATCH 120/254] py: client: fix docs for get_model_artifacts Behaviour for getting a single ma given an mv_id is not documented as it's not an assumed use case. Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 3 +++ clients/python/src/model_registry/client.py | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/clients/python/README.md b/clients/python/README.md index f0a32c51..d4eca55b 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -136,6 +136,9 @@ versions = registry.get_model_versions("registered_model_id") # We can get associated model artifacts with the versions model_artifacts = [version.model for version in versions] + +# We can also get a list of all model artifacts +all_model_artifacts = registry.get_model_artifacts() ``` To limit or order the query, provide a [`ListOptions`](src/model_registry/types/options.py) object diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index b68c439d..1226aa20 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -378,12 +378,20 @@ def get_model_artifact_by_params( assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" return py_ma - # TODO: does this call make sense? def get_model_artifacts( self, model_version_id: Optional[str] = None, options: Optional[ListOptions] = None, ) -> Sequence[ModelArtifact]: + """Fetches model artifacts. + + Args: + model_version_id (str, optional): ID of the associated model version. + options (ListOptions, optional): Options for listing model artifacts. + + Returns: + Sequence[ModelArtifact]: Model artifacts. + """ mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() if model_version_id is not None: mlmd_options.filter_query = f"contexts_a.id = {model_version_id}" From 303bb38ba583bc89ec8131413b36dd9fe8ebedea Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 7 Nov 2023 19:11:15 -0300 Subject: [PATCH 121/254] py: tests: separate cases for get_model_artifacts This also simplifies the base case as we don't actually need versions to make this query. Signed-off-by: Isabella Basso do Amaral --- clients/python/tests/registry/test_client.py | 0 clients/python/tests/test_client.py | 21 ++++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) delete mode 100644 clients/python/tests/registry/test_client.py diff --git a/clients/python/tests/registry/test_client.py b/clients/python/tests/registry/test_client.py deleted file mode 100644 index e69de29b..00000000 diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index d2c5575d..7f39634a 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -430,7 +430,20 @@ def test_get_model_artifact_by_external_id( assert mlmd_ma.name != model.proto.name -def test_get_model_artifacts( +def test_get_all_model_artifacts( + model_registry: ModelRegistry, model: Mapped, model_version: Mapped +): + model.proto.name = "test_prefix:model1" + ma1_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + model.proto.name = "test_prefix:model2" + ma2_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] + + mlmd_mas = model_registry.get_model_artifacts() + assert len(mlmd_mas) == 2 + assert mlmd_mas[0].id in [str(ma1_id), str(ma2_id)] + + +def test_get_model_artifacts_by_mv_id( model_registry: ModelRegistry, model: Mapped, model_version: Mapped ): mv1_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] @@ -451,6 +464,6 @@ def test_get_model_artifacts( [], ) - mlmd_mas = model_registry.get_model_artifacts() - assert len(mlmd_mas) == 2 - assert mlmd_mas[0].id in [str(ma1_id), str(ma2_id)] + mlmd_mas = model_registry.get_model_artifacts(str(mv1_id)) + assert len(mlmd_mas) == 1 + assert mlmd_mas[0].id == str(ma1_id) From 1a7a4138d88267602b4901946e0956b5f1a09d1b Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Tue, 14 Nov 2023 08:51:53 +0100 Subject: [PATCH 122/254] Make model registry core importable as library (#140) --- Makefile | 8 +-- cmd/proxy.go | 2 +- internal/{core => apiutils}/api_utils.go | 20 +++--- internal/{core => mapper}/mapper.go | 2 +- .../api_model_registry_service_service.go | 24 +++---- {internal/core => pkg/api}/api.go | 2 +- {internal => pkg}/core/core.go | 70 +++++++++---------- {internal => pkg}/core/core_test.go | 59 ++++++++-------- test/bdd/mr_service_features_test.go | 5 +- 9 files changed, 98 insertions(+), 94 deletions(-) rename internal/{core => apiutils}/api_utils.go (76%) rename internal/{core => mapper}/mapper.go (99%) rename {internal/core => pkg/api}/api.go (99%) rename {internal => pkg}/core/core.go (93%) rename {internal => pkg}/core/core_test.go (98%) diff --git a/Makefile b/Makefile index b43de570..fa9d46f6 100644 --- a/Makefile +++ b/Makefile @@ -163,19 +163,19 @@ gen: deps gen/grpc gen/openapi gen/converter gen/graph .PHONY: lint lint: gen golangci-lint run main.go - golangci-lint run cmd/... internal/... + golangci-lint run cmd/... internal/... ./pkg/... .PHONY: test test: gen - go test ./internal/... + go test ./internal/... ./pkg/... .PHONY: test-nocache test-nocache: gen - go test ./internal/... -count=1 + go test ./internal/... ./pkg/... -count=1 .PHONY: test-cover test-cover: gen - go test ./internal/... -cover -count=1 + go test ./internal/... ./pkg/... -cover -count=1 .PHONY: run/migrate run/migrate: gen diff --git a/cmd/proxy.go b/cmd/proxy.go index 348f6a72..fb2b8656 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -7,8 +7,8 @@ import ( "net/http" "github.com/golang/glog" - "github.com/opendatahub-io/model-registry/internal/core" "github.com/opendatahub-io/model-registry/internal/server/openapi" + "github.com/opendatahub-io/model-registry/pkg/core" "github.com/spf13/cobra" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" diff --git a/internal/core/api_utils.go b/internal/apiutils/api_utils.go similarity index 76% rename from internal/core/api_utils.go rename to internal/apiutils/api_utils.go index a3a4f010..444091a4 100644 --- a/internal/core/api_utils.go +++ b/internal/apiutils/api_utils.go @@ -1,17 +1,11 @@ -package core +package apiutils import ( "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/pkg/api" ) -func zeroIfNil[T any](input *T) T { - if input != nil { - return *input - } - return *new(T) -} - -func BuildListOperationOptions(listOptions ListOptions) (*proto.ListOperationOptions, error) { +func BuildListOperationOptions(listOptions api.ListOptions) (*proto.ListOperationOptions, error) { result := proto.ListOperationOptions{} if listOptions.PageSize != nil { @@ -41,3 +35,11 @@ func BuildListOperationOptions(listOptions ListOptions) (*proto.ListOperationOpt } return &result, nil } + +// ZeroIfNil return the zeroed value if input is a nil pointer +func ZeroIfNil[T any](input *T) T { + if input != nil { + return *input + } + return *new(T) +} diff --git a/internal/core/mapper.go b/internal/mapper/mapper.go similarity index 99% rename from internal/core/mapper.go rename to internal/mapper/mapper.go index d68b3dd5..e4140b4e 100644 --- a/internal/core/mapper.go +++ b/internal/mapper/mapper.go @@ -1,4 +1,4 @@ -package core +package mapper import ( "fmt" diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index 7369dad5..dd507ff7 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -16,20 +16,20 @@ import ( "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/converter/generated" - "github.com/opendatahub-io/model-registry/internal/core" model "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/api" ) // ModelRegistryServiceAPIService is a service that implements the logic for the ModelRegistryServiceAPIServicer // This service should implement the business logic for every endpoint for the ModelRegistryServiceAPI s.coreApi. // Include any external packages or services that will be required by this service. type ModelRegistryServiceAPIService struct { - coreApi core.ModelRegistryApi + coreApi api.ModelRegistryApi converter converter.OpenAPIConverter } // NewModelRegistryServiceAPIService creates a default api service -func NewModelRegistryServiceAPIService(coreApi core.ModelRegistryApi) ModelRegistryServiceAPIServicer { +func NewModelRegistryServiceAPIService(coreApi api.ModelRegistryApi) ModelRegistryServiceAPIServicer { return &ModelRegistryServiceAPIService{ coreApi: coreApi, converter: &generated.OpenAPIConverterImpl{}, @@ -237,7 +237,7 @@ func (s *ModelRegistryServiceAPIService) GetEnvironmentInferenceServices(ctx con if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetInferenceServices(core.ListOptions{ + result, err := s.coreApi.GetInferenceServices(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -281,7 +281,7 @@ func (s *ModelRegistryServiceAPIService) GetInferenceServiceServes(ctx context.C if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetServeModels(core.ListOptions{ + result, err := s.coreApi.GetServeModels(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -314,7 +314,7 @@ func (s *ModelRegistryServiceAPIService) GetInferenceServices(ctx context.Contex if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetInferenceServices(core.ListOptions{ + result, err := s.coreApi.GetInferenceServices(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -347,7 +347,7 @@ func (s *ModelRegistryServiceAPIService) GetModelArtifacts(ctx context.Context, if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelArtifacts(core.ListOptions{ + result, err := s.coreApi.GetModelArtifacts(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -383,7 +383,7 @@ func (s *ModelRegistryServiceAPIService) GetModelVersionArtifacts(ctx context.Co if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelArtifacts(core.ListOptions{ + result, err := s.coreApi.GetModelArtifacts(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -405,7 +405,7 @@ func (s *ModelRegistryServiceAPIService) GetModelVersions(ctx context.Context, p if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelVersions(core.ListOptions{ + result, err := s.coreApi.GetModelVersions(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -441,7 +441,7 @@ func (s *ModelRegistryServiceAPIService) GetRegisteredModelVersions(ctx context. if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelVersions(core.ListOptions{ + result, err := s.coreApi.GetModelVersions(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -463,7 +463,7 @@ func (s *ModelRegistryServiceAPIService) GetRegisteredModels(ctx context.Context if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetRegisteredModels(core.ListOptions{ + result, err := s.coreApi.GetRegisteredModels(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, @@ -497,7 +497,7 @@ func (s *ModelRegistryServiceAPIService) GetServingEnvironments(ctx context.Cont if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetServingEnvironments(core.ListOptions{ + result, err := s.coreApi.GetServingEnvironments(api.ListOptions{ PageSize: &pageSizeInt32, OrderBy: &orderByString, SortOrder: &sortOrderString, diff --git a/internal/core/api.go b/pkg/api/api.go similarity index 99% rename from internal/core/api.go rename to pkg/api/api.go index 3757474c..5e22d961 100644 --- a/internal/core/api.go +++ b/pkg/api/api.go @@ -1,4 +1,4 @@ -package core +package api import "github.com/opendatahub-io/model-registry/internal/model/openapi" diff --git a/internal/core/core.go b/pkg/core/core.go similarity index 93% rename from internal/core/core.go rename to pkg/core/core.go index 19dc01ae..4d429cd2 100644 --- a/internal/core/core.go +++ b/pkg/core/core.go @@ -5,9 +5,12 @@ import ( "fmt" "github.com/golang/glog" + "github.com/opendatahub-io/model-registry/internal/apiutils" "github.com/opendatahub-io/model-registry/internal/converter" + "github.com/opendatahub-io/model-registry/internal/mapper" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/api" "google.golang.org/grpc" ) @@ -23,11 +26,11 @@ var ( // modelRegistryService is the core library of the model registry type modelRegistryService struct { mlmdClient proto.MetadataStoreServiceClient - mapper *Mapper + mapper *mapper.Mapper } // NewModelRegistryService create a fresh instance of ModelRegistryService, taking care of setting up needed MLMD Types -func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, error) { +func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, error) { client := proto.NewMetadataStoreServiceClient(cc) @@ -84,8 +87,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err "description": proto.PropertyType_STRING, "model_version_id": proto.PropertyType_INT, "registered_model_id": proto.PropertyType_INT, - // TODO: check with Andrea, my understanding is parent/child is only for ownership of ServingEnvironment/InferenceService (moving comment down 1 line for serving_environment_id) - // we could remove this as we will use ParentContext to keep track of this association + // same information tracked using ParentContext association "serving_environment_id": proto.PropertyType_INT, }, }, @@ -95,9 +97,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err ExecutionType: &proto.ExecutionType{ Name: serveModelTypeName, Properties: map[string]proto.PropertyType{ - "description": proto.PropertyType_STRING, - // TODO: check with Andrea, my understanding is parent/child is only for ownership of InferenceService/ServeModel via MLMD Association (Execution ServeModel --> Context InferenceService) - // we could remove this as we will use ParentContext to keep track of this association + "description": proto.PropertyType_STRING, "model_version_id": proto.PropertyType_INT, "runtime": proto.PropertyType_STRING, }, @@ -136,7 +136,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (ModelRegistryApi, err return &modelRegistryService{ mlmdClient: client, - mapper: NewMapper( + mapper: mapper.NewMapper( registeredModelResp.GetTypeId(), modelVersionResp.GetTypeId(), modelArtifactResp.GetTypeId(), @@ -296,8 +296,8 @@ func (serv *modelRegistryService) GetRegisteredModelByParams(name *string, exter return regModel, nil } -func (serv *modelRegistryService) GetRegisteredModels(listOptions ListOptions) (*openapi.RegisteredModelList, error) { - listOperationOptions, err := BuildListOperationOptions(listOptions) +func (serv *modelRegistryService) GetRegisteredModels(listOptions api.ListOptions) (*openapi.RegisteredModelList, error) { + listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } @@ -319,8 +319,8 @@ func (serv *modelRegistryService) GetRegisteredModels(listOptions ListOptions) ( } toReturn := openapi.RegisteredModelList{ - NextPageToken: zeroIfNil(contextsResp.NextPageToken), - PageSize: zeroIfNil(listOptions.PageSize), + NextPageToken: apiutils.ZeroIfNil(contextsResp.NextPageToken), + PageSize: apiutils.ZeroIfNil(listOptions.PageSize), Size: int32(len(results)), Items: results, } @@ -445,7 +445,7 @@ func (serv *modelRegistryService) GetModelVersionByInferenceService(inferenceSer // modelVersionId: ID of the ModelVersion to serve. If it's unspecified, then the latest ModelVersion by creation order will be served. orderByCreateTime := "CREATE_TIME" sortOrderDesc := "DESC" - versions, err := serv.GetModelVersions(ListOptions{OrderBy: &orderByCreateTime, SortOrder: &sortOrderDesc}, &is.RegisteredModelId) + versions, err := serv.GetModelVersions(api.ListOptions{OrderBy: &orderByCreateTime, SortOrder: &sortOrderDesc}, &is.RegisteredModelId) if err != nil { return nil, err } @@ -507,7 +507,7 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p } if len(getByParamsResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple model versions found for versionName=%v, parentResourceId=%v, externalId=%v", zeroIfNil(versionName), zeroIfNil(parentResourceId), zeroIfNil(externalId)) + return nil, fmt.Errorf("multiple model versions found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(versionName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) } modelVer, err := serv.mapper.MapToModelVersion(getByParamsResp.Contexts[0]) @@ -517,8 +517,8 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p return modelVer, nil } -func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) { - listOperationOptions, err := BuildListOperationOptions(listOptions) +func (serv *modelRegistryService) GetModelVersions(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) { + listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } @@ -546,8 +546,8 @@ func (serv *modelRegistryService) GetModelVersions(listOptions ListOptions, pare } toReturn := openapi.ModelVersionList{ - NextPageToken: zeroIfNil(contextsResp.NextPageToken), - PageSize: zeroIfNil(listOptions.PageSize), + NextPageToken: apiutils.ZeroIfNil(contextsResp.NextPageToken), + PageSize: apiutils.ZeroIfNil(listOptions.PageSize), Size: int32(len(results)), Items: results, } @@ -697,8 +697,8 @@ func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, return result, nil } -func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) { - listOperationOptions, err := BuildListOperationOptions(listOptions) +func (serv *modelRegistryService) GetModelArtifacts(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) { + listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } @@ -741,8 +741,8 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions ListOptions, par } toReturn := openapi.ModelArtifactList{ - NextPageToken: zeroIfNil(nextPageToken), - PageSize: zeroIfNil(listOptions.PageSize), + NextPageToken: apiutils.ZeroIfNil(nextPageToken), + PageSize: apiutils.ZeroIfNil(listOptions.PageSize), Size: int32(len(results)), Items: results, } @@ -859,8 +859,8 @@ func (serv *modelRegistryService) GetServingEnvironmentByParams(name *string, ex return openapiModel, nil } -func (serv *modelRegistryService) GetServingEnvironments(listOptions ListOptions) (*openapi.ServingEnvironmentList, error) { - listOperationOptions, err := BuildListOperationOptions(listOptions) +func (serv *modelRegistryService) GetServingEnvironments(listOptions api.ListOptions) (*openapi.ServingEnvironmentList, error) { + listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } @@ -882,8 +882,8 @@ func (serv *modelRegistryService) GetServingEnvironments(listOptions ListOptions } toReturn := openapi.ServingEnvironmentList{ - NextPageToken: zeroIfNil(contextsResp.NextPageToken), - PageSize: zeroIfNil(listOptions.PageSize), + NextPageToken: apiutils.ZeroIfNil(contextsResp.NextPageToken), + PageSize: apiutils.ZeroIfNil(listOptions.PageSize), Size: int32(len(results)), Items: results, } @@ -1053,7 +1053,7 @@ func (serv *modelRegistryService) GetInferenceServiceByParams(name *string, pare } if len(getByParamsResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple InferenceServices found for name=%v, parentResourceId=%v, externalId=%v", zeroIfNil(name), zeroIfNil(parentResourceId), zeroIfNil(externalId)) + return nil, fmt.Errorf("multiple InferenceServices found for name=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) } toReturn, err := serv.mapper.MapToInferenceService(getByParamsResp.Contexts[0]) @@ -1063,8 +1063,8 @@ func (serv *modelRegistryService) GetInferenceServiceByParams(name *string, pare return toReturn, nil } -func (serv *modelRegistryService) GetInferenceServices(listOptions ListOptions, parentResourceId *string) (*openapi.InferenceServiceList, error) { - listOperationOptions, err := BuildListOperationOptions(listOptions) +func (serv *modelRegistryService) GetInferenceServices(listOptions api.ListOptions, parentResourceId *string) (*openapi.InferenceServiceList, error) { + listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } @@ -1092,8 +1092,8 @@ func (serv *modelRegistryService) GetInferenceServices(listOptions ListOptions, } toReturn := openapi.InferenceServiceList{ - NextPageToken: zeroIfNil(contextsResp.NextPageToken), - PageSize: zeroIfNil(listOptions.PageSize), + NextPageToken: apiutils.ZeroIfNil(contextsResp.NextPageToken), + PageSize: apiutils.ZeroIfNil(listOptions.PageSize), Size: int32(len(results)), Items: results, } @@ -1242,8 +1242,8 @@ func (serv *modelRegistryService) GetServeModelById(id string) (*openapi.ServeMo return result, nil } -func (serv *modelRegistryService) GetServeModels(listOptions ListOptions, parentResourceId *string) (*openapi.ServeModelList, error) { - listOperationOptions, err := BuildListOperationOptions(listOptions) +func (serv *modelRegistryService) GetServeModels(listOptions api.ListOptions, parentResourceId *string) (*openapi.ServeModelList, error) { + listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } @@ -1286,8 +1286,8 @@ func (serv *modelRegistryService) GetServeModels(listOptions ListOptions, parent } toReturn := openapi.ServeModelList{ - NextPageToken: zeroIfNil(nextPageToken), - PageSize: zeroIfNil(listOptions.PageSize), + NextPageToken: apiutils.ZeroIfNil(nextPageToken), + PageSize: apiutils.ZeroIfNil(listOptions.PageSize), Size: int32(len(results)), Items: results, } diff --git a/internal/core/core_test.go b/pkg/core/core_test.go similarity index 98% rename from internal/core/core_test.go rename to pkg/core/core_test.go index 85c3bb29..1edf53bb 100644 --- a/internal/core/core_test.go +++ b/pkg/core/core_test.go @@ -9,6 +9,7 @@ import ( "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" "github.com/opendatahub-io/model-registry/internal/testutils" + "github.com/opendatahub-io/model-registry/pkg/api" "github.com/stretchr/testify/assert" "google.golang.org/grpc" ) @@ -71,14 +72,14 @@ func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataSt } // initialize model registry service and assert no error is thrown -func initModelRegistryService(assertion *assert.Assertions, conn *grpc.ClientConn) ModelRegistryApi { +func initModelRegistryService(assertion *assert.Assertions, conn *grpc.ClientConn) api.ModelRegistryApi { service, err := NewModelRegistryService(conn) assertion.Nilf(err, "error creating core service: %v", err) return service } // utility function that register a new simple model and return its ID -func registerModel(assertion *assert.Assertions, service ModelRegistryApi, overrideModelName *string, overrideExternalId *string) string { +func registerModel(assertion *assert.Assertions, service api.ModelRegistryApi, overrideModelName *string, overrideExternalId *string) string { registeredModel := &openapi.RegisteredModel{ Name: &modelName, ExternalID: &modelExternalId, @@ -108,7 +109,7 @@ func registerModel(assertion *assert.Assertions, service ModelRegistryApi, overr } // utility function that register a new simple ServingEnvironment and return its ID -func registerServingEnvironment(assertion *assert.Assertions, service ModelRegistryApi, overrideName *string, overrideExternalId *string) string { +func registerServingEnvironment(assertion *assert.Assertions, service api.ModelRegistryApi, overrideName *string, overrideExternalId *string) string { eutName := "Simple ServingEnvironment" eutExtID := "Simple ServingEnvironment ExtID" eut := &openapi.ServingEnvironment{ @@ -142,7 +143,7 @@ func registerServingEnvironment(assertion *assert.Assertions, service ModelRegis // utility function that register a new simple model and return its ID func registerModelVersion( assertion *assert.Assertions, - service ModelRegistryApi, + service api.ModelRegistryApi, overrideModelName *string, overrideExternalId *string, overrideVersionName *string, @@ -178,7 +179,7 @@ func registerModelVersion( } // utility function that register a new simple ServingEnvironment and return its ID -func registerInferenceService(assertion *assert.Assertions, service ModelRegistryApi, registerdModelId string, overrideParentResourceName *string, overrideParentResourceExternalId *string, overrideName *string, overrideExternalId *string) string { +func registerInferenceService(assertion *assert.Assertions, service api.ModelRegistryApi, registerdModelId string, overrideParentResourceName *string, overrideParentResourceExternalId *string, overrideName *string, overrideExternalId *string) string { servingEnvironmentId := registerServingEnvironment(assertion, service, overrideParentResourceName, overrideParentResourceExternalId) eutName := "simpleInferenceService" @@ -510,7 +511,7 @@ func TestGetRegisteredModelsOrderedById(t *testing.T) { _, err = service.UpsertRegisteredModel(registeredModel) assertion.Nilf(err, "error creating registered model: %v", err) - orderedById, err := service.GetRegisteredModels(ListOptions{ + orderedById, err := service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) @@ -521,7 +522,7 @@ func TestGetRegisteredModelsOrderedById(t *testing.T) { assertion.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) } - orderedById, err = service.GetRegisteredModels(ListOptions{ + orderedById, err = service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) @@ -570,7 +571,7 @@ func TestGetRegisteredModelsOrderedByLastUpdate(t *testing.T) { _, err = service.UpsertRegisteredModel(secondModel) assertion.Nilf(err, "error creating registered model: %v", err) - orderedById, err := service.GetRegisteredModels(ListOptions{ + orderedById, err := service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) @@ -581,7 +582,7 @@ func TestGetRegisteredModelsOrderedByLastUpdate(t *testing.T) { assertion.Equal(*thirdModel.Id, *orderedById.Items[1].Id) assertion.Equal(*secondModel.Id, *orderedById.Items[2].Id) - orderedById, err = service.GetRegisteredModels(ListOptions{ + orderedById, err = service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) @@ -628,7 +629,7 @@ func TestGetRegisteredModelsWithPageSize(t *testing.T) { thirdModel, err := service.UpsertRegisteredModel(registeredModel) assertion.Nilf(err, "error creating registered model: %v", err) - truncatedList, err := service.GetRegisteredModels(ListOptions{ + truncatedList, err := service.GetRegisteredModels(api.ListOptions{ PageSize: &pageSize, }) assertion.Nilf(err, "error getting registered models: %v", err) @@ -637,7 +638,7 @@ func TestGetRegisteredModelsWithPageSize(t *testing.T) { assertion.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") assertion.Equal(*firstModel.Id, *truncatedList.Items[0].Id) - truncatedList, err = service.GetRegisteredModels(ListOptions{ + truncatedList, err = service.GetRegisteredModels(api.ListOptions{ PageSize: &pageSize2, NextPageToken: &truncatedList.NextPageToken, }) @@ -1078,11 +1079,11 @@ func TestGetModelVersions(t *testing.T) { createdVersionId2, _ := converter.StringToInt64(createdVersion2.Id) createdVersionId3, _ := converter.StringToInt64(createdVersion3.Id) - getAll, err := service.GetModelVersions(ListOptions{}, nil) + getAll, err := service.GetModelVersions(api.ListOptions{}, nil) assertion.Nilf(err, "error getting all model versions") assertion.Equal(int32(4), getAll.Size, "expected four model versions across all registered models") - getAllByRegModel, err := service.GetModelVersions(ListOptions{}, ®isteredModelId) + getAllByRegModel, err := service.GetModelVersions(api.ListOptions{}, ®isteredModelId) assertion.Nilf(err, "error getting all model versions") assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) @@ -1092,7 +1093,7 @@ func TestGetModelVersions(t *testing.T) { // order by last update time, expecting last created as first orderByLastUpdate := "LAST_UPDATE_TIME" - getAllByRegModel, err = service.GetModelVersions(ListOptions{ + getAllByRegModel, err = service.GetModelVersions(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, ®isteredModelId) @@ -1111,7 +1112,7 @@ func TestGetModelVersions(t *testing.T) { assertion.Equal(newVersionExternalId, *createdVersion2.ExternalID) - getAllByRegModel, err = service.GetModelVersions(ListOptions{ + getAllByRegModel, err = service.GetModelVersions(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, ®isteredModelId) @@ -1489,7 +1490,7 @@ func TestGetModelArtifacts(t *testing.T) { createdArtifactId2, _ := converter.StringToInt64(createdArtifact2.Id) createdArtifactId3, _ := converter.StringToInt64(createdArtifact3.Id) - getAll, err := service.GetModelArtifacts(ListOptions{}, nil) + getAll, err := service.GetModelArtifacts(api.ListOptions{}, nil) assertion.Nilf(err, "error getting all model artifacts") assertion.Equalf(int32(3), getAll.Size, "expected three model artifacts") @@ -1498,7 +1499,7 @@ func TestGetModelArtifacts(t *testing.T) { assertion.Equal(*converter.Int64ToString(createdArtifactId3), *getAll.Items[2].Id) orderByLastUpdate := "LAST_UPDATE_TIME" - getAllByModelVersion, err := service.GetModelArtifacts(ListOptions{ + getAllByModelVersion, err := service.GetModelArtifacts(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &modelVersionId) @@ -1781,7 +1782,7 @@ func TestGetServingEnvironmentsOrderedById(t *testing.T) { _, err = service.UpsertServingEnvironment(eut) assertion.Nilf(err, "error creating ServingEnvironment: %v", err) - orderedById, err := service.GetServingEnvironments(ListOptions{ + orderedById, err := service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) @@ -1792,7 +1793,7 @@ func TestGetServingEnvironmentsOrderedById(t *testing.T) { assertion.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) } - orderedById, err = service.GetServingEnvironments(ListOptions{ + orderedById, err = service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) @@ -1841,7 +1842,7 @@ func TestGetServingEnvironmentsOrderedByLastUpdate(t *testing.T) { _, err = service.UpsertServingEnvironment(secondEntity) assertion.Nilf(err, "error creating ServingEnvironment: %v", err) - orderedById, err := service.GetServingEnvironments(ListOptions{ + orderedById, err := service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) @@ -1852,7 +1853,7 @@ func TestGetServingEnvironmentsOrderedByLastUpdate(t *testing.T) { assertion.Equal(*thirdEntity.Id, *orderedById.Items[1].Id) assertion.Equal(*secondEntity.Id, *orderedById.Items[2].Id) - orderedById, err = service.GetServingEnvironments(ListOptions{ + orderedById, err = service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) @@ -1899,7 +1900,7 @@ func TestGetServingEnvironmentsWithPageSize(t *testing.T) { thirdEntity, err := service.UpsertServingEnvironment(eut) assertion.Nilf(err, "error creating ServingEnvironment: %v", err) - truncatedList, err := service.GetServingEnvironments(ListOptions{ + truncatedList, err := service.GetServingEnvironments(api.ListOptions{ PageSize: &pageSize, }) assertion.Nilf(err, "error getting ServingEnvironments: %v", err) @@ -1908,7 +1909,7 @@ func TestGetServingEnvironmentsWithPageSize(t *testing.T) { assertion.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") assertion.Equal(*firstEntity.Id, *truncatedList.Items[0].Id) - truncatedList, err = service.GetServingEnvironments(ListOptions{ + truncatedList, err = service.GetServingEnvironments(api.ListOptions{ PageSize: &pageSize2, NextPageToken: &truncatedList.NextPageToken, }) @@ -2482,11 +2483,11 @@ func TestGetInferenceServices(t *testing.T) { createdId2, _ := converter.StringToInt64(createdEntity2.Id) createdId3, _ := converter.StringToInt64(createdEntity3.Id) - getAll, err := service.GetInferenceServices(ListOptions{}, nil) + getAll, err := service.GetInferenceServices(api.ListOptions{}, nil) assertion.Nilf(err, "error getting all") assertion.Equal(int32(4), getAll.Size, "expected 4 across all parent resources") - getAllByParentResource, err := service.GetInferenceServices(ListOptions{}, &parentResourceId) + getAllByParentResource, err := service.GetInferenceServices(api.ListOptions{}, &parentResourceId) assertion.Nilf(err, "error getting all") assertion.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) @@ -2496,7 +2497,7 @@ func TestGetInferenceServices(t *testing.T) { // order by last update time, expecting last created as first orderByLastUpdate := "LAST_UPDATE_TIME" - getAllByParentResource, err = service.GetInferenceServices(ListOptions{ + getAllByParentResource, err = service.GetInferenceServices(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &parentResourceId) @@ -2515,7 +2516,7 @@ func TestGetInferenceServices(t *testing.T) { assertion.Equal(newExternalId, *createdEntity2.ExternalID) - getAllByParentResource, err = service.GetInferenceServices(ListOptions{ + getAllByParentResource, err = service.GetInferenceServices(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &parentResourceId) @@ -2907,7 +2908,7 @@ func TestGetServeModels(t *testing.T) { createdEntityId2, _ := converter.StringToInt64(createdEntity2.Id) createdEntityId3, _ := converter.StringToInt64(createdEntity3.Id) - getAll, err := service.GetServeModels(ListOptions{}, nil) + getAll, err := service.GetServeModels(api.ListOptions{}, nil) assertion.Nilf(err, "error getting all ServeModel") assertion.Equalf(int32(3), getAll.Size, "expected three ServeModel") @@ -2916,7 +2917,7 @@ func TestGetServeModels(t *testing.T) { assertion.Equal(*converter.Int64ToString(createdEntityId3), *getAll.Items[2].Id) orderByLastUpdate := "LAST_UPDATE_TIME" - getAllByInferenceService, err := service.GetServeModels(ListOptions{ + getAllByInferenceService, err := service.GetServeModels(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &inferenceServiceId) diff --git a/test/bdd/mr_service_features_test.go b/test/bdd/mr_service_features_test.go index 0860bea2..c61445b7 100644 --- a/test/bdd/mr_service_features_test.go +++ b/test/bdd/mr_service_features_test.go @@ -8,9 +8,10 @@ import ( "testing" "github.com/cucumber/godog" - "github.com/opendatahub-io/model-registry/internal/core" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/api" + "github.com/opendatahub-io/model-registry/pkg/core" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" "google.golang.org/grpc" @@ -67,7 +68,7 @@ func iHaveAConnectionToMR(ctx context.Context) (context.Context, error) { } func iStoreARegisteredModelWithNameAndAChildModelVersionWithNameAndAChildArtifactWithUri(ctx context.Context, registedModelName, modelVersionName, artifactURI string) error { - service, ok := ctx.Value(svcLayerCtxKey{}).(core.ModelRegistryApi) + service, ok := ctx.Value(svcLayerCtxKey{}).(api.ModelRegistryApi) if !ok { return fmt.Errorf("not found service layer connection in godog context") } From 9d9d48fd332d864395b37aff2fc546e79bc432e7 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Tue, 14 Nov 2023 09:39:09 +0100 Subject: [PATCH 123/254] Create BuildListOption for REST query params (#139) * Create BuildListOption for REST query params * Implement code review feedback * Dockerfile: copy pkg source folder --------- Co-authored-by: Andrea Lamparelli --- Dockerfile | 1 + internal/apiutils/api_utils.go | 31 ++++++ .../api_model_registry_service_service.go | 100 ++++-------------- 3 files changed, 51 insertions(+), 81 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5c98e25a..5c8f7303 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,6 +30,7 @@ COPY cmd/ cmd/ COPY api/ api/ COPY config/ config/ COPY internal/ internal/ +COPY pkg/ pkg/ # Build USER root diff --git a/internal/apiutils/api_utils.go b/internal/apiutils/api_utils.go index 444091a4..fb930d8c 100644 --- a/internal/apiutils/api_utils.go +++ b/internal/apiutils/api_utils.go @@ -1,7 +1,9 @@ package apiutils import ( + "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + model "github.com/opendatahub-io/model-registry/internal/model/openapi" "github.com/opendatahub-io/model-registry/pkg/api" ) @@ -43,3 +45,32 @@ func ZeroIfNil[T any](input *T) T { } return *new(T) } + +func BuildListOption(pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (api.ListOptions, error) { + var pageSizeInt32 *int32 + if pageSize != "" { + conv, err := converter.StringToInt32(pageSize) + if err != nil { + return api.ListOptions{}, err + } + pageSizeInt32 = &conv + } + var orderByString *string + if orderBy != "" { + orderByString = (*string)(&orderBy) + } + var sortOrderString *string + if sortOrder != "" { + sortOrderString = (*string)(&sortOrder) + } + var nextPageTokenParam *string + if nextPageToken != "" { + nextPageTokenParam = &nextPageToken + } + return api.ListOptions{ + PageSize: pageSizeInt32, + OrderBy: orderByString, + SortOrder: sortOrderString, + NextPageToken: nextPageTokenParam, + }, nil +} diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index dd507ff7..c22c0dcc 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -14,6 +14,7 @@ import ( "errors" "net/http" + "github.com/opendatahub-io/model-registry/internal/apiutils" "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/converter/generated" model "github.com/opendatahub-io/model-registry/internal/model/openapi" @@ -231,18 +232,11 @@ func (s *ModelRegistryServiceAPIService) FindServingEnvironment(ctx context.Cont // GetEnvironmentInferenceServices - List All ServingEnvironment's InferenceServices func (s *ModelRegistryServiceAPIService) GetEnvironmentInferenceServices(ctx context.Context, servingenvironmentId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetInferenceServices(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }, &servingenvironmentId) + result, err := s.coreApi.GetInferenceServices(listOpts, &servingenvironmentId) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -275,18 +269,11 @@ func (s *ModelRegistryServiceAPIService) GetInferenceServiceModel(ctx context.Co // GetInferenceServiceServes - List All InferenceService's ServeModel actions func (s *ModelRegistryServiceAPIService) GetInferenceServiceServes(ctx context.Context, inferenceserviceId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetServeModels(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }, &inferenceserviceId) + result, err := s.coreApi.GetServeModels(listOpts, &inferenceserviceId) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -308,18 +295,11 @@ func (s *ModelRegistryServiceAPIService) GetInferenceServiceVersion(ctx context. // GetInferenceServices - List All InferenceServices func (s *ModelRegistryServiceAPIService) GetInferenceServices(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetInferenceServices(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }, nil) + result, err := s.coreApi.GetInferenceServices(listOpts, nil) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -341,18 +321,11 @@ func (s *ModelRegistryServiceAPIService) GetModelArtifact(ctx context.Context, m // GetModelArtifacts - List All ModelArtifacts func (s *ModelRegistryServiceAPIService) GetModelArtifacts(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelArtifacts(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }, nil) + result, err := s.coreApi.GetModelArtifacts(listOpts, nil) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -377,18 +350,11 @@ func (s *ModelRegistryServiceAPIService) GetModelVersion(ctx context.Context, mo func (s *ModelRegistryServiceAPIService) GetModelVersionArtifacts(ctx context.Context, modelversionId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { // TODO name unused // TODO externalID unused - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelArtifacts(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }, &modelversionId) + result, err := s.coreApi.GetModelArtifacts(listOpts, &modelversionId) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -399,18 +365,11 @@ func (s *ModelRegistryServiceAPIService) GetModelVersionArtifacts(ctx context.Co // GetModelVersions - List All ModelVersions func (s *ModelRegistryServiceAPIService) GetModelVersions(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelVersions(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }, nil) + result, err := s.coreApi.GetModelVersions(listOpts, nil) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -435,18 +394,11 @@ func (s *ModelRegistryServiceAPIService) GetRegisteredModel(ctx context.Context, func (s *ModelRegistryServiceAPIService) GetRegisteredModelVersions(ctx context.Context, registeredmodelId string, name string, externalID string, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { // TODO name unused // TODO externalID unused - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelVersions(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }, ®isteredmodelId) + result, err := s.coreApi.GetModelVersions(listOpts, ®isteredmodelId) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -457,18 +409,11 @@ func (s *ModelRegistryServiceAPIService) GetRegisteredModelVersions(ctx context. // GetRegisteredModels - List All RegisteredModels func (s *ModelRegistryServiceAPIService) GetRegisteredModels(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetRegisteredModels(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }) + result, err := s.coreApi.GetRegisteredModels(listOpts) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -491,18 +436,11 @@ func (s *ModelRegistryServiceAPIService) GetServingEnvironment(ctx context.Conte // GetServingEnvironments - List All ServingEnvironments func (s *ModelRegistryServiceAPIService) GetServingEnvironments(ctx context.Context, pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (ImplResponse, error) { - orderByString := string(orderBy) - sortOrderString := string(sortOrder) - pageSizeInt32, err := converter.StringToInt32(pageSize) + listOpts, err := apiutils.BuildListOption(pageSize, orderBy, sortOrder, nextPageToken) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetServingEnvironments(api.ListOptions{ - PageSize: &pageSizeInt32, - OrderBy: &orderByString, - SortOrder: &sortOrderString, - NextPageToken: &nextPageToken, - }) + result, err := s.coreApi.GetServingEnvironments(listOpts) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } From 2c1381edb6997994b8642c1ab18ce4d1c8cddcec Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Tue, 14 Nov 2023 09:45:41 +0100 Subject: [PATCH 124/254] python check: do not ignore the workflow itself --- .github/workflows/python-client.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml index 83645bd6..0d8cce5a 100644 --- a/.github/workflows/python-client.yml +++ b/.github/workflows/python-client.yml @@ -7,6 +7,7 @@ on: pull_request: paths: - "clients/python/**" + - ".github/workflows/python-client.yml" jobs: tests: From 3ad11b96ab74f7fe649bbf6eaa3a8834cdf40211 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 14 Nov 2023 13:02:21 +0000 Subject: [PATCH 125/254] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/python-client.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml index 0d8cce5a..12d0d14c 100644 --- a/.github/workflows/python-client.yml +++ b/.github/workflows/python-client.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Check out the repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v4.6.1 From 3c39415cd17de050b1f04dedc0045464a2bf6fdd Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Tue, 14 Nov 2023 14:20:54 +0100 Subject: [PATCH 126/254] Improve converter testing (#141) * Improve converter testing * Update internal/converter/mlmd_converter_util_test.go * Update internal/converter/mlmd_converter_util_test.go Co-authored-by: Matteo Mortari --------- Co-authored-by: Matteo Mortari --- .../converter/mlmd_converter_util_test.go | 209 +++++++++++++++++- pkg/core/core_test.go | 5 + 2 files changed, 209 insertions(+), 5 deletions(-) diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index 797ce96d..f823a8da 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -44,6 +44,23 @@ func TestInt64ToString(t *testing.T) { assertion.Nil(Int64ToString(nil)) } +func TestStringToInt32(t *testing.T) { + assertion := setup(t) + + valid := "12345" + converted, err := StringToInt32(valid) + assertion.Nil(err) + assertion.Equal(int32(12345), converted) +} + +func TestStringToInt32InvalidNumber(t *testing.T) { + assertion := setup(t) + + invalid := "not-a-number" + _, err := StringToInt32(invalid) + assertion.NotNil(err) +} + func TestMetadataValueBool(t *testing.T) { data := make(map[string]openapi.MetadataValue) key := "my bool" @@ -173,7 +190,14 @@ func TestPrefixWhenOwnedWithoutOwner(t *testing.T) { func TestMapRegisteredModelProperties(t *testing.T) { assertion := setup(t) - props, err := MapRegisteredModelProperties(&openapi.RegisteredModel{}) + props, err := MapRegisteredModelProperties(&openapi.RegisteredModel{ + Description: of("super description"), + }) + assertion.Nil(err) + assertion.Equal(1, len(props)) + assertion.Equal("super description", props["description"].GetStringValue()) + + props, err = MapRegisteredModelProperties(&openapi.RegisteredModel{}) assertion.Nil(err) assertion.Equal(0, len(props)) } @@ -194,12 +218,14 @@ func TestMapModelVersionProperties(t *testing.T) { ParentResourceId: of("123"), ModelName: of("MyModel"), Model: &openapi.ModelVersion{ - Name: of("v1"), + Name: of("v1"), + Description: of("my model version description"), }, }) assertion.Nil(err) - assertion.Equal(3, len(props)) - // TODO check all 3 props + assertion.Equal(4, len(props)) + assertion.Equal("my model version description", props["description"].GetStringValue()) + assertion.Equal("v1", props["version"].GetStringValue()) } func TestMapModelVersionType(t *testing.T) { @@ -230,6 +256,7 @@ func TestMapModelArtifactProperties(t *testing.T) { props, err := MapModelArtifactProperties(&openapi.ModelArtifact{ Name: of("v1"), + Description: of("my model art description"), ModelFormatName: of("sklearn"), ModelFormatVersion: of("1.0"), StorageKey: of("storage-key"), @@ -237,7 +264,8 @@ func TestMapModelArtifactProperties(t *testing.T) { ServiceAccountName: of("service-account-name"), }) assertion.Nil(err) - assertion.Equal(5, len(props)) + assertion.Equal(6, len(props)) + assertion.Equal("my model art description", props["description"].GetStringValue()) assertion.Equal("sklearn", props["model_format_name"].GetStringValue()) assertion.Equal("1.0", props["model_format_version"].GetStringValue()) assertion.Equal("storage-key", props["storage_key"].GetStringValue()) @@ -411,6 +439,62 @@ func TestMapModelArtifactServiceAccountName(t *testing.T) { assertion.Equal("my-account", *extracted) } +func TestMapPropertyModelVersionId(t *testing.T) { + assertion := setup(t) + + extracted := MapPropertyModelVersionId(map[string]*proto.Value{ + "model_version_id": { + Value: &proto.Value_IntValue{ + IntValue: 123, + }, + }, + }) + + assertion.Equal("123", *extracted) +} + +func TestMapPropertyModelVersionIdAsValue(t *testing.T) { + assertion := setup(t) + + extracted := MapPropertyModelVersionIdAsValue(map[string]*proto.Value{ + "model_version_id": { + Value: &proto.Value_IntValue{ + IntValue: 123, + }, + }, + }) + + assertion.Equal("123", extracted) +} + +func TestMapPropertyRegisteredModelId(t *testing.T) { + assertion := setup(t) + + extracted := MapPropertyRegisteredModelId(map[string]*proto.Value{ + "registered_model_id": { + Value: &proto.Value_IntValue{ + IntValue: 123, + }, + }, + }) + + assertion.Equal("123", extracted) +} + +func TestMapPropertyServingEnvironmentId(t *testing.T) { + assertion := setup(t) + + extracted := MapPropertyServingEnvironmentId(map[string]*proto.Value{ + "serving_environment_id": { + Value: &proto.Value_IntValue{ + IntValue: 123, + }, + }, + }) + + assertion.Equal("123", extracted) +} + func TestMapNameFromOwned(t *testing.T) { assertion := setup(t) @@ -519,3 +603,118 @@ func TestMapServeModelProperties(t *testing.T) { assertion.NotNil(err) assertion.Equal(0, len(props)) } + +func TestMapServingEnvironmentProperties(t *testing.T) { + assertion := setup(t) + + props, err := MapServingEnvironmentProperties(&openapi.ServingEnvironment{ + Description: of("my description"), + }) + assertion.Nil(err) + assertion.Equal(1, len(props)) + + props, err = MapServingEnvironmentProperties(&openapi.ServingEnvironment{}) + assertion.Nil(err) + assertion.Equal(0, len(props)) +} + +func TestMapInferenceServiceName(t *testing.T) { + assertion := setup(t) + + name := MapInferenceServiceName(&OpenAPIModelWrapper[openapi.InferenceService]{ + TypeId: 123, + ParentResourceId: of("123"), + ModelName: of("MyModel"), + Model: &openapi.InferenceService{ + Name: of("inf-service"), + }, + }) + assertion.NotNil(name) + assertion.Equal("123:inf-service", *name) +} + +func TestMapServeModelName(t *testing.T) { + assertion := setup(t) + + name := MapServeModelName(&OpenAPIModelWrapper[openapi.ServeModel]{ + TypeId: 123, + ParentResourceId: of("parent"), + Model: &openapi.ServeModel{ + Name: of("v1"), + }, + }) + assertion.NotNil(name) + assertion.Equal("parent:v1", *name) + + name = MapServeModelName(&OpenAPIModelWrapper[openapi.ServeModel]{ + TypeId: 123, + ParentResourceId: of("parent"), + Model: &openapi.ServeModel{ + Name: nil, + }, + }) + assertion.NotNil(name) + assertion.Regexp("parent:.*", *name) + + name = MapServeModelName(&OpenAPIModelWrapper[openapi.ServeModel]{ + TypeId: 123, + Model: &openapi.ServeModel{ + Name: of("v1"), + }, + }) + assertion.NotNil(name) + assertion.Regexp(".*:v1", *name) +} + +func TestMapLastKnownState(t *testing.T) { + assertion := setup(t) + + state, err := MapLastKnownState(of(openapi.EXECUTIONSTATE_RUNNING)) + assertion.Nil(err) + assertion.Equal("RUNNING", state.String()) + + state, err = MapLastKnownState(nil) + assertion.Nil(err) + assertion.Nil(state) +} + +func TestMapIntProperty(t *testing.T) { + assertion := setup(t) + + props := map[string]*proto.Value{ + "key": { + Value: &proto.Value_IntValue{ + IntValue: 10, + }, + }, + } + + assertion.Equal("10", *MapIntProperty(props, "key")) + assertion.Nil(MapIntProperty(props, "not-present")) +} + +func TestMapIntPropertyAsValue(t *testing.T) { + assertion := setup(t) + + props := map[string]*proto.Value{ + "key": { + Value: &proto.Value_IntValue{ + IntValue: 10, + }, + }, + } + + assertion.Equal("10", MapIntPropertyAsValue(props, "key")) + assertion.Equal("", MapIntPropertyAsValue(props, "not-present")) +} + +func TestMapMLMDServeModelLastKnownState(t *testing.T) { + assertion := setup(t) + + state := MapMLMDServeModelLastKnownState(of(proto.Execution_COMPLETE)) + assertion.NotNil(state) + assertion.Equal("COMPLETE", string(*state)) + + state = MapMLMDServeModelLastKnownState(nil) + assertion.Nil(state) +} diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index 1edf53bb..6738e777 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -45,6 +45,11 @@ var ( ) func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { + if testing.Short() { + // skip these tests using -short param + t.Skip("skipping testing in short mode") + } + // initialize test variable before each test ascOrderDirection = "ASC" descOrderDirection = "DESC" From 4932968fff7f0cb9e9d306429c388e249ce363c1 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Tue, 14 Nov 2023 17:39:52 +0100 Subject: [PATCH 127/254] Make core models importable (#149) --- .openapi-generator-ignore | 28 +++++++++---------- Makefile | 12 ++++---- internal/apiutils/api_utils.go | 2 +- .../generated/mlmd_openapi_converter.gen.go | 2 +- .../generated/openapi_converter.gen.go | 2 +- .../generated/openapi_mlmd_converter.gen.go | 2 +- .../converter/mlmd_converter_util_test.go | 2 +- internal/converter/mlmd_openapi_converter.go | 2 +- .../converter/mlmd_openapi_converter_util.go | 2 +- internal/converter/opeanpi_converter.go | 2 +- internal/converter/openapi_mlmd_converter.go | 2 +- .../converter/openapi_mlmd_converter_util.go | 2 +- internal/mapper/mapper.go | 2 +- internal/server/openapi/api.go | 2 +- .../openapi/api_model_registry_service.go | 2 +- .../api_model_registry_service_service.go | 2 +- internal/server/openapi/type_asserts.go | 2 +- pkg/api/api.go | 2 +- pkg/core/core.go | 2 +- pkg/core/core_test.go | 2 +- .../openapi/.openapi-generator/FILES | 0 .../openapi/.openapi-generator/VERSION | 0 .../openapi/api_model_registry_service.go | 0 {internal/model => pkg}/openapi/client.go | 0 .../model => pkg}/openapi/configuration.go | 0 .../model => pkg}/openapi/model_artifact.go | 0 .../openapi/model_artifact_list.go | 0 .../openapi/model_artifact_state.go | 0 .../openapi/model_base_artifact.go | 0 .../openapi/model_base_artifact_create.go | 0 .../openapi/model_base_artifact_update.go | 0 .../openapi/model_base_execution.go | 0 .../openapi/model_base_execution_create.go | 0 .../openapi/model_base_execution_update.go | 0 .../openapi/model_base_resource.go | 0 .../openapi/model_base_resource_create.go | 0 .../openapi/model_base_resource_list.go | 0 .../openapi/model_base_resource_update.go | 0 .../model => pkg}/openapi/model_error.go | 0 .../openapi/model_execution_state.go | 0 .../openapi/model_inference_service.go | 0 .../openapi/model_inference_service_create.go | 0 .../openapi/model_inference_service_list.go | 0 .../openapi/model_inference_service_update.go | 0 .../openapi/model_metadata_bool_value.go | 0 .../openapi/model_metadata_double_value.go | 0 .../openapi/model_metadata_int_value.go | 0 .../openapi/model_metadata_proto_value.go | 0 .../openapi/model_metadata_string_value.go | 0 .../openapi/model_metadata_struct_value.go | 0 .../openapi/model_metadata_value.go | 0 .../openapi/model_model_artifact.go | 0 .../openapi/model_model_artifact_create.go | 0 .../openapi/model_model_artifact_list.go | 0 .../openapi/model_model_artifact_update.go | 0 .../openapi/model_model_version.go | 0 .../openapi/model_model_version_create.go | 0 .../openapi/model_model_version_list.go | 0 .../openapi/model_model_version_update.go | 0 .../openapi/model_order_by_field.go | 0 .../openapi/model_registered_model.go | 0 .../openapi/model_registered_model_create.go | 0 .../openapi/model_registered_model_list.go | 0 .../openapi/model_registered_model_update.go | 0 .../openapi/model_serve_model.go | 0 .../openapi/model_serve_model_create.go | 0 .../openapi/model_serve_model_list.go | 0 .../openapi/model_serve_model_update.go | 0 .../openapi/model_serving_environment.go | 0 .../model_serving_environment_create.go | 0 .../openapi/model_serving_environment_list.go | 0 .../model_serving_environment_update.go | 0 .../model => pkg}/openapi/model_sort_order.go | 0 {internal/model => pkg}/openapi/response.go | 0 {internal/model => pkg}/openapi/utils.go | 0 scripts/gen_type_asserts.sh | 2 +- test/bdd/mr_service_features_test.go | 2 +- 77 files changed, 40 insertions(+), 40 deletions(-) rename {internal/model => pkg}/openapi/.openapi-generator/FILES (100%) rename {internal/model => pkg}/openapi/.openapi-generator/VERSION (100%) rename {internal/model => pkg}/openapi/api_model_registry_service.go (100%) rename {internal/model => pkg}/openapi/client.go (100%) rename {internal/model => pkg}/openapi/configuration.go (100%) rename {internal/model => pkg}/openapi/model_artifact.go (100%) rename {internal/model => pkg}/openapi/model_artifact_list.go (100%) rename {internal/model => pkg}/openapi/model_artifact_state.go (100%) rename {internal/model => pkg}/openapi/model_base_artifact.go (100%) rename {internal/model => pkg}/openapi/model_base_artifact_create.go (100%) rename {internal/model => pkg}/openapi/model_base_artifact_update.go (100%) rename {internal/model => pkg}/openapi/model_base_execution.go (100%) rename {internal/model => pkg}/openapi/model_base_execution_create.go (100%) rename {internal/model => pkg}/openapi/model_base_execution_update.go (100%) rename {internal/model => pkg}/openapi/model_base_resource.go (100%) rename {internal/model => pkg}/openapi/model_base_resource_create.go (100%) rename {internal/model => pkg}/openapi/model_base_resource_list.go (100%) rename {internal/model => pkg}/openapi/model_base_resource_update.go (100%) rename {internal/model => pkg}/openapi/model_error.go (100%) rename {internal/model => pkg}/openapi/model_execution_state.go (100%) rename {internal/model => pkg}/openapi/model_inference_service.go (100%) rename {internal/model => pkg}/openapi/model_inference_service_create.go (100%) rename {internal/model => pkg}/openapi/model_inference_service_list.go (100%) rename {internal/model => pkg}/openapi/model_inference_service_update.go (100%) rename {internal/model => pkg}/openapi/model_metadata_bool_value.go (100%) rename {internal/model => pkg}/openapi/model_metadata_double_value.go (100%) rename {internal/model => pkg}/openapi/model_metadata_int_value.go (100%) rename {internal/model => pkg}/openapi/model_metadata_proto_value.go (100%) rename {internal/model => pkg}/openapi/model_metadata_string_value.go (100%) rename {internal/model => pkg}/openapi/model_metadata_struct_value.go (100%) rename {internal/model => pkg}/openapi/model_metadata_value.go (100%) rename {internal/model => pkg}/openapi/model_model_artifact.go (100%) rename {internal/model => pkg}/openapi/model_model_artifact_create.go (100%) rename {internal/model => pkg}/openapi/model_model_artifact_list.go (100%) rename {internal/model => pkg}/openapi/model_model_artifact_update.go (100%) rename {internal/model => pkg}/openapi/model_model_version.go (100%) rename {internal/model => pkg}/openapi/model_model_version_create.go (100%) rename {internal/model => pkg}/openapi/model_model_version_list.go (100%) rename {internal/model => pkg}/openapi/model_model_version_update.go (100%) rename {internal/model => pkg}/openapi/model_order_by_field.go (100%) rename {internal/model => pkg}/openapi/model_registered_model.go (100%) rename {internal/model => pkg}/openapi/model_registered_model_create.go (100%) rename {internal/model => pkg}/openapi/model_registered_model_list.go (100%) rename {internal/model => pkg}/openapi/model_registered_model_update.go (100%) rename {internal/model => pkg}/openapi/model_serve_model.go (100%) rename {internal/model => pkg}/openapi/model_serve_model_create.go (100%) rename {internal/model => pkg}/openapi/model_serve_model_list.go (100%) rename {internal/model => pkg}/openapi/model_serve_model_update.go (100%) rename {internal/model => pkg}/openapi/model_serving_environment.go (100%) rename {internal/model => pkg}/openapi/model_serving_environment_create.go (100%) rename {internal/model => pkg}/openapi/model_serving_environment_list.go (100%) rename {internal/model => pkg}/openapi/model_serving_environment_update.go (100%) rename {internal/model => pkg}/openapi/model_sort_order.go (100%) rename {internal/model => pkg}/openapi/response.go (100%) rename {internal/model => pkg}/openapi/utils.go (100%) diff --git a/.openapi-generator-ignore b/.openapi-generator-ignore index 254e4377..18a46d80 100644 --- a/.openapi-generator-ignore +++ b/.openapi-generator-ignore @@ -23,20 +23,20 @@ #!docs/README.md # model and client files -internal/model/openapi/api -internal/model/openapi/api/** -internal/model/openapi/git_push.sh -internal/model/openapi/.gitignore -internal/model/openapi/.travis.yml -internal/model/openapi/.openapi-generator-ignore - -internal/model/openapi/README.md -internal/model/openapi/docs/**.md -internal/model/openapi/test -internal/model/openapi/test/** -internal/model/openapi/**all_of.go -internal/model/openapi/go.mod -internal/model/openapi/go.sum +pkg/openapi/api +pkg/openapi/api/** +pkg/openapi/git_push.sh +pkg/openapi/.gitignore +pkg/openapi/.travis.yml +pkg/openapi/.openapi-generator-ignore + +pkg/openapi/README.md +pkg/openapi/docs/**.md +pkg/openapi/test +pkg/openapi/test/** +pkg/openapi/**all_of.go +pkg/openapi/go.mod +pkg/openapi/go.sum # server files to ignore internal/server/openapi/api diff --git a/Makefile b/Makefile index fa9d46f6..9bbcaa75 100644 --- a/Makefile +++ b/Makefile @@ -88,14 +88,14 @@ gen/openapi-server: bin/openapi-generator-cli openapi/validate # generate the openapi schema model and client .PHONY: gen/openapi -gen/openapi: bin/openapi-generator-cli openapi/validate internal/model/openapi/client.go +gen/openapi: bin/openapi-generator-cli openapi/validate pkg/openapi/client.go -internal/model/openapi/client.go: bin/openapi-generator-cli api/openapi/model-registry.yaml - rm -rf internal/model/openapi +pkg/openapi/client.go: bin/openapi-generator-cli api/openapi/model-registry.yaml + rm -rf pkg/openapi openapi-generator-cli generate \ - -i api/openapi/model-registry.yaml -g go -o internal/model/openapi --package-name openapi \ + -i api/openapi/model-registry.yaml -g go -o pkg/openapi --package-name openapi \ --ignore-file-override ./.openapi-generator-ignore --additional-properties=isGoSubmodule=true,enumClassPrefix=true,useOneOfDiscriminatorLookup=true - gofmt -w internal/model/openapi + gofmt -w pkg/openapi .PHONY: vet vet: @@ -103,7 +103,7 @@ vet: .PHONY: clean clean: - rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/*.go internal/model/openapi + rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/*.go pkg/openapi bin/go-enum: GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 diff --git a/internal/apiutils/api_utils.go b/internal/apiutils/api_utils.go index fb930d8c..8f5aaf49 100644 --- a/internal/apiutils/api_utils.go +++ b/internal/apiutils/api_utils.go @@ -3,8 +3,8 @@ package apiutils import ( "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" "github.com/opendatahub-io/model-registry/pkg/api" + model "github.com/opendatahub-io/model-registry/pkg/openapi" ) func BuildListOperationOptions(listOptions api.ListOptions) (*proto.ListOperationOptions, error) { diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index 403734d5..7eaa270a 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -6,7 +6,7 @@ import ( "fmt" converter "github.com/opendatahub-io/model-registry/internal/converter" proto "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - openapi "github.com/opendatahub-io/model-registry/internal/model/openapi" + openapi "github.com/opendatahub-io/model-registry/pkg/openapi" ) type MLMDToOpenAPIConverterImpl struct{} diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index a27563b7..accd966d 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -2,7 +2,7 @@ package generated -import openapi "github.com/opendatahub-io/model-registry/internal/model/openapi" +import openapi "github.com/opendatahub-io/model-registry/pkg/openapi" type OpenAPIConverterImpl struct{} diff --git a/internal/converter/generated/openapi_mlmd_converter.gen.go b/internal/converter/generated/openapi_mlmd_converter.gen.go index 1e3552b6..f7cd116e 100755 --- a/internal/converter/generated/openapi_mlmd_converter.gen.go +++ b/internal/converter/generated/openapi_mlmd_converter.gen.go @@ -6,7 +6,7 @@ import ( "fmt" converter "github.com/opendatahub-io/model-registry/internal/converter" proto "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - openapi "github.com/opendatahub-io/model-registry/internal/model/openapi" + openapi "github.com/opendatahub-io/model-registry/pkg/openapi" ) type OpenAPIToMLMDConverterImpl struct{} diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index f823a8da..74b5d0b5 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/openapi" "github.com/stretchr/testify/assert" "golang.org/x/exp/maps" ) diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index fb3d2125..8d28c3a2 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -2,7 +2,7 @@ package converter import ( "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/openapi" ) // goverter:converter diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 634382be..44d206b1 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -7,7 +7,7 @@ import ( "strings" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/openapi" ) // MapMLMDCustomProperties maps MLMD custom properties model to OpenAPI one diff --git a/internal/converter/opeanpi_converter.go b/internal/converter/opeanpi_converter.go index 74446cdc..46163b85 100644 --- a/internal/converter/opeanpi_converter.go +++ b/internal/converter/opeanpi_converter.go @@ -1,6 +1,6 @@ package converter -import "github.com/opendatahub-io/model-registry/internal/model/openapi" +import "github.com/opendatahub-io/model-registry/pkg/openapi" // goverter:converter // goverter:output:file ./generated/openapi_converter.gen.go diff --git a/internal/converter/openapi_mlmd_converter.go b/internal/converter/openapi_mlmd_converter.go index cbab8bf6..3db5be72 100644 --- a/internal/converter/openapi_mlmd_converter.go +++ b/internal/converter/openapi_mlmd_converter.go @@ -2,7 +2,7 @@ package converter import ( "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/openapi" ) const ( diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index bd0b886e..d3b28034 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -8,7 +8,7 @@ import ( "github.com/google/uuid" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/openapi" "google.golang.org/protobuf/types/known/structpb" ) diff --git a/internal/mapper/mapper.go b/internal/mapper/mapper.go index e4140b4e..cff7f23d 100644 --- a/internal/mapper/mapper.go +++ b/internal/mapper/mapper.go @@ -6,7 +6,7 @@ import ( "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/converter/generated" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" + "github.com/opendatahub-io/model-registry/pkg/openapi" ) type Mapper struct { diff --git a/internal/server/openapi/api.go b/internal/server/openapi/api.go index e7c8d241..d4a7584e 100644 --- a/internal/server/openapi/api.go +++ b/internal/server/openapi/api.go @@ -13,7 +13,7 @@ import ( "context" "net/http" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" + model "github.com/opendatahub-io/model-registry/pkg/openapi" ) // ModelRegistryServiceAPIRouter defines the required methods for binding the api requests to a responses for the ModelRegistryServiceAPI diff --git a/internal/server/openapi/api_model_registry_service.go b/internal/server/openapi/api_model_registry_service.go index 29c94029..e079b090 100644 --- a/internal/server/openapi/api_model_registry_service.go +++ b/internal/server/openapi/api_model_registry_service.go @@ -15,7 +15,7 @@ import ( "strings" "github.com/go-chi/chi/v5" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" + model "github.com/opendatahub-io/model-registry/pkg/openapi" ) // ModelRegistryServiceAPIController binds http requests to an api service and writes the service results to the http response diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index c22c0dcc..dedfaf32 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -17,8 +17,8 @@ import ( "github.com/opendatahub-io/model-registry/internal/apiutils" "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/converter/generated" - model "github.com/opendatahub-io/model-registry/internal/model/openapi" "github.com/opendatahub-io/model-registry/pkg/api" + model "github.com/opendatahub-io/model-registry/pkg/openapi" ) // ModelRegistryServiceAPIService is a service that implements the logic for the ModelRegistryServiceAPIServicer diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go index 2aba64a0..07a7e94b 100644 --- a/internal/server/openapi/type_asserts.go +++ b/internal/server/openapi/type_asserts.go @@ -13,7 +13,7 @@ package openapi import ( - model "github.com/opendatahub-io/model-registry/internal/model/openapi" + model "github.com/opendatahub-io/model-registry/pkg/openapi" ) // AssertArtifactRequired checks if the required fields are not zero-ed diff --git a/pkg/api/api.go b/pkg/api/api.go index 5e22d961..5c33a07a 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -1,6 +1,6 @@ package api -import "github.com/opendatahub-io/model-registry/internal/model/openapi" +import "github.com/opendatahub-io/model-registry/pkg/openapi" type ListOptions struct { PageSize *int32 diff --git a/pkg/core/core.go b/pkg/core/core.go index 4d429cd2..709b1218 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -9,8 +9,8 @@ import ( "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/mapper" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" "github.com/opendatahub-io/model-registry/pkg/api" + "github.com/opendatahub-io/model-registry/pkg/openapi" "google.golang.org/grpc" ) diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index 6738e777..7187837e 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -7,9 +7,9 @@ import ( "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/openapi" "github.com/opendatahub-io/model-registry/internal/testutils" "github.com/opendatahub-io/model-registry/pkg/api" + "github.com/opendatahub-io/model-registry/pkg/openapi" "github.com/stretchr/testify/assert" "google.golang.org/grpc" ) diff --git a/internal/model/openapi/.openapi-generator/FILES b/pkg/openapi/.openapi-generator/FILES similarity index 100% rename from internal/model/openapi/.openapi-generator/FILES rename to pkg/openapi/.openapi-generator/FILES diff --git a/internal/model/openapi/.openapi-generator/VERSION b/pkg/openapi/.openapi-generator/VERSION similarity index 100% rename from internal/model/openapi/.openapi-generator/VERSION rename to pkg/openapi/.openapi-generator/VERSION diff --git a/internal/model/openapi/api_model_registry_service.go b/pkg/openapi/api_model_registry_service.go similarity index 100% rename from internal/model/openapi/api_model_registry_service.go rename to pkg/openapi/api_model_registry_service.go diff --git a/internal/model/openapi/client.go b/pkg/openapi/client.go similarity index 100% rename from internal/model/openapi/client.go rename to pkg/openapi/client.go diff --git a/internal/model/openapi/configuration.go b/pkg/openapi/configuration.go similarity index 100% rename from internal/model/openapi/configuration.go rename to pkg/openapi/configuration.go diff --git a/internal/model/openapi/model_artifact.go b/pkg/openapi/model_artifact.go similarity index 100% rename from internal/model/openapi/model_artifact.go rename to pkg/openapi/model_artifact.go diff --git a/internal/model/openapi/model_artifact_list.go b/pkg/openapi/model_artifact_list.go similarity index 100% rename from internal/model/openapi/model_artifact_list.go rename to pkg/openapi/model_artifact_list.go diff --git a/internal/model/openapi/model_artifact_state.go b/pkg/openapi/model_artifact_state.go similarity index 100% rename from internal/model/openapi/model_artifact_state.go rename to pkg/openapi/model_artifact_state.go diff --git a/internal/model/openapi/model_base_artifact.go b/pkg/openapi/model_base_artifact.go similarity index 100% rename from internal/model/openapi/model_base_artifact.go rename to pkg/openapi/model_base_artifact.go diff --git a/internal/model/openapi/model_base_artifact_create.go b/pkg/openapi/model_base_artifact_create.go similarity index 100% rename from internal/model/openapi/model_base_artifact_create.go rename to pkg/openapi/model_base_artifact_create.go diff --git a/internal/model/openapi/model_base_artifact_update.go b/pkg/openapi/model_base_artifact_update.go similarity index 100% rename from internal/model/openapi/model_base_artifact_update.go rename to pkg/openapi/model_base_artifact_update.go diff --git a/internal/model/openapi/model_base_execution.go b/pkg/openapi/model_base_execution.go similarity index 100% rename from internal/model/openapi/model_base_execution.go rename to pkg/openapi/model_base_execution.go diff --git a/internal/model/openapi/model_base_execution_create.go b/pkg/openapi/model_base_execution_create.go similarity index 100% rename from internal/model/openapi/model_base_execution_create.go rename to pkg/openapi/model_base_execution_create.go diff --git a/internal/model/openapi/model_base_execution_update.go b/pkg/openapi/model_base_execution_update.go similarity index 100% rename from internal/model/openapi/model_base_execution_update.go rename to pkg/openapi/model_base_execution_update.go diff --git a/internal/model/openapi/model_base_resource.go b/pkg/openapi/model_base_resource.go similarity index 100% rename from internal/model/openapi/model_base_resource.go rename to pkg/openapi/model_base_resource.go diff --git a/internal/model/openapi/model_base_resource_create.go b/pkg/openapi/model_base_resource_create.go similarity index 100% rename from internal/model/openapi/model_base_resource_create.go rename to pkg/openapi/model_base_resource_create.go diff --git a/internal/model/openapi/model_base_resource_list.go b/pkg/openapi/model_base_resource_list.go similarity index 100% rename from internal/model/openapi/model_base_resource_list.go rename to pkg/openapi/model_base_resource_list.go diff --git a/internal/model/openapi/model_base_resource_update.go b/pkg/openapi/model_base_resource_update.go similarity index 100% rename from internal/model/openapi/model_base_resource_update.go rename to pkg/openapi/model_base_resource_update.go diff --git a/internal/model/openapi/model_error.go b/pkg/openapi/model_error.go similarity index 100% rename from internal/model/openapi/model_error.go rename to pkg/openapi/model_error.go diff --git a/internal/model/openapi/model_execution_state.go b/pkg/openapi/model_execution_state.go similarity index 100% rename from internal/model/openapi/model_execution_state.go rename to pkg/openapi/model_execution_state.go diff --git a/internal/model/openapi/model_inference_service.go b/pkg/openapi/model_inference_service.go similarity index 100% rename from internal/model/openapi/model_inference_service.go rename to pkg/openapi/model_inference_service.go diff --git a/internal/model/openapi/model_inference_service_create.go b/pkg/openapi/model_inference_service_create.go similarity index 100% rename from internal/model/openapi/model_inference_service_create.go rename to pkg/openapi/model_inference_service_create.go diff --git a/internal/model/openapi/model_inference_service_list.go b/pkg/openapi/model_inference_service_list.go similarity index 100% rename from internal/model/openapi/model_inference_service_list.go rename to pkg/openapi/model_inference_service_list.go diff --git a/internal/model/openapi/model_inference_service_update.go b/pkg/openapi/model_inference_service_update.go similarity index 100% rename from internal/model/openapi/model_inference_service_update.go rename to pkg/openapi/model_inference_service_update.go diff --git a/internal/model/openapi/model_metadata_bool_value.go b/pkg/openapi/model_metadata_bool_value.go similarity index 100% rename from internal/model/openapi/model_metadata_bool_value.go rename to pkg/openapi/model_metadata_bool_value.go diff --git a/internal/model/openapi/model_metadata_double_value.go b/pkg/openapi/model_metadata_double_value.go similarity index 100% rename from internal/model/openapi/model_metadata_double_value.go rename to pkg/openapi/model_metadata_double_value.go diff --git a/internal/model/openapi/model_metadata_int_value.go b/pkg/openapi/model_metadata_int_value.go similarity index 100% rename from internal/model/openapi/model_metadata_int_value.go rename to pkg/openapi/model_metadata_int_value.go diff --git a/internal/model/openapi/model_metadata_proto_value.go b/pkg/openapi/model_metadata_proto_value.go similarity index 100% rename from internal/model/openapi/model_metadata_proto_value.go rename to pkg/openapi/model_metadata_proto_value.go diff --git a/internal/model/openapi/model_metadata_string_value.go b/pkg/openapi/model_metadata_string_value.go similarity index 100% rename from internal/model/openapi/model_metadata_string_value.go rename to pkg/openapi/model_metadata_string_value.go diff --git a/internal/model/openapi/model_metadata_struct_value.go b/pkg/openapi/model_metadata_struct_value.go similarity index 100% rename from internal/model/openapi/model_metadata_struct_value.go rename to pkg/openapi/model_metadata_struct_value.go diff --git a/internal/model/openapi/model_metadata_value.go b/pkg/openapi/model_metadata_value.go similarity index 100% rename from internal/model/openapi/model_metadata_value.go rename to pkg/openapi/model_metadata_value.go diff --git a/internal/model/openapi/model_model_artifact.go b/pkg/openapi/model_model_artifact.go similarity index 100% rename from internal/model/openapi/model_model_artifact.go rename to pkg/openapi/model_model_artifact.go diff --git a/internal/model/openapi/model_model_artifact_create.go b/pkg/openapi/model_model_artifact_create.go similarity index 100% rename from internal/model/openapi/model_model_artifact_create.go rename to pkg/openapi/model_model_artifact_create.go diff --git a/internal/model/openapi/model_model_artifact_list.go b/pkg/openapi/model_model_artifact_list.go similarity index 100% rename from internal/model/openapi/model_model_artifact_list.go rename to pkg/openapi/model_model_artifact_list.go diff --git a/internal/model/openapi/model_model_artifact_update.go b/pkg/openapi/model_model_artifact_update.go similarity index 100% rename from internal/model/openapi/model_model_artifact_update.go rename to pkg/openapi/model_model_artifact_update.go diff --git a/internal/model/openapi/model_model_version.go b/pkg/openapi/model_model_version.go similarity index 100% rename from internal/model/openapi/model_model_version.go rename to pkg/openapi/model_model_version.go diff --git a/internal/model/openapi/model_model_version_create.go b/pkg/openapi/model_model_version_create.go similarity index 100% rename from internal/model/openapi/model_model_version_create.go rename to pkg/openapi/model_model_version_create.go diff --git a/internal/model/openapi/model_model_version_list.go b/pkg/openapi/model_model_version_list.go similarity index 100% rename from internal/model/openapi/model_model_version_list.go rename to pkg/openapi/model_model_version_list.go diff --git a/internal/model/openapi/model_model_version_update.go b/pkg/openapi/model_model_version_update.go similarity index 100% rename from internal/model/openapi/model_model_version_update.go rename to pkg/openapi/model_model_version_update.go diff --git a/internal/model/openapi/model_order_by_field.go b/pkg/openapi/model_order_by_field.go similarity index 100% rename from internal/model/openapi/model_order_by_field.go rename to pkg/openapi/model_order_by_field.go diff --git a/internal/model/openapi/model_registered_model.go b/pkg/openapi/model_registered_model.go similarity index 100% rename from internal/model/openapi/model_registered_model.go rename to pkg/openapi/model_registered_model.go diff --git a/internal/model/openapi/model_registered_model_create.go b/pkg/openapi/model_registered_model_create.go similarity index 100% rename from internal/model/openapi/model_registered_model_create.go rename to pkg/openapi/model_registered_model_create.go diff --git a/internal/model/openapi/model_registered_model_list.go b/pkg/openapi/model_registered_model_list.go similarity index 100% rename from internal/model/openapi/model_registered_model_list.go rename to pkg/openapi/model_registered_model_list.go diff --git a/internal/model/openapi/model_registered_model_update.go b/pkg/openapi/model_registered_model_update.go similarity index 100% rename from internal/model/openapi/model_registered_model_update.go rename to pkg/openapi/model_registered_model_update.go diff --git a/internal/model/openapi/model_serve_model.go b/pkg/openapi/model_serve_model.go similarity index 100% rename from internal/model/openapi/model_serve_model.go rename to pkg/openapi/model_serve_model.go diff --git a/internal/model/openapi/model_serve_model_create.go b/pkg/openapi/model_serve_model_create.go similarity index 100% rename from internal/model/openapi/model_serve_model_create.go rename to pkg/openapi/model_serve_model_create.go diff --git a/internal/model/openapi/model_serve_model_list.go b/pkg/openapi/model_serve_model_list.go similarity index 100% rename from internal/model/openapi/model_serve_model_list.go rename to pkg/openapi/model_serve_model_list.go diff --git a/internal/model/openapi/model_serve_model_update.go b/pkg/openapi/model_serve_model_update.go similarity index 100% rename from internal/model/openapi/model_serve_model_update.go rename to pkg/openapi/model_serve_model_update.go diff --git a/internal/model/openapi/model_serving_environment.go b/pkg/openapi/model_serving_environment.go similarity index 100% rename from internal/model/openapi/model_serving_environment.go rename to pkg/openapi/model_serving_environment.go diff --git a/internal/model/openapi/model_serving_environment_create.go b/pkg/openapi/model_serving_environment_create.go similarity index 100% rename from internal/model/openapi/model_serving_environment_create.go rename to pkg/openapi/model_serving_environment_create.go diff --git a/internal/model/openapi/model_serving_environment_list.go b/pkg/openapi/model_serving_environment_list.go similarity index 100% rename from internal/model/openapi/model_serving_environment_list.go rename to pkg/openapi/model_serving_environment_list.go diff --git a/internal/model/openapi/model_serving_environment_update.go b/pkg/openapi/model_serving_environment_update.go similarity index 100% rename from internal/model/openapi/model_serving_environment_update.go rename to pkg/openapi/model_serving_environment_update.go diff --git a/internal/model/openapi/model_sort_order.go b/pkg/openapi/model_sort_order.go similarity index 100% rename from internal/model/openapi/model_sort_order.go rename to pkg/openapi/model_sort_order.go diff --git a/internal/model/openapi/response.go b/pkg/openapi/response.go similarity index 100% rename from internal/model/openapi/response.go rename to pkg/openapi/response.go diff --git a/internal/model/openapi/utils.go b/pkg/openapi/utils.go similarity index 100% rename from internal/model/openapi/utils.go rename to pkg/openapi/utils.go diff --git a/scripts/gen_type_asserts.sh b/scripts/gen_type_asserts.sh index 03f2a9ba..b49f650a 100755 --- a/scripts/gen_type_asserts.sh +++ b/scripts/gen_type_asserts.sh @@ -29,7 +29,7 @@ INITIAL_CONTENT=$(cat < Date: Wed, 15 Nov 2023 14:20:24 +0100 Subject: [PATCH 128/254] Fix docker compose setup (#142) --- cmd/proxy.go | 12 +++++++++--- docker-compose-local.yaml | 10 +++++----- docker-compose.yaml | 11 +++++------ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/cmd/proxy.go b/cmd/proxy.go index fb2b8656..ecdfa64e 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "time" "github.com/golang/glog" "github.com/opendatahub-io/model-registry/internal/server/openapi" @@ -28,12 +29,15 @@ hostname and port where it listens.'`, ) func runProxyServer(cmd *cobra.Command, args []string) error { - glog.Infof("proxy server started at %s:%v", cfg.Hostname, cfg.Port) + glog.Infof("Proxy server started at %s:%v", cfg.Hostname, cfg.Port) + + ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() mlmdAddr := fmt.Sprintf("%s:%d", proxyCfg.MLMDHostname, proxyCfg.MLMDPort) - glog.Infof("MLMD server %s", mlmdAddr) + glog.Infof("Connecting to MLMD server %s..", mlmdAddr) conn, err := grpc.DialContext( - context.Background(), + ctxTimeout, mlmdAddr, grpc.WithReturnConnectionError(), grpc.WithBlock(), @@ -44,6 +48,8 @@ func runProxyServer(cmd *cobra.Command, args []string) error { return err } defer conn.Close() + glog.Infof("Connected to MLMD server") + service, err := core.NewModelRegistryService(conn) if err != nil { log.Fatalf("Error creating core service: %v", err) diff --git a/docker-compose-local.yaml b/docker-compose-local.yaml index 380624cc..cddf36f8 100644 --- a/docker-compose-local.yaml +++ b/docker-compose-local.yaml @@ -1,10 +1,10 @@ version: '3' services: - ml-metadata: + mlmd-server: image: gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0 container_name: mlmd-server ports: - - "8080:8080" + - "9090:8080" environment: - METADATA_STORE_SERVER_CONFIG_FILE=/tmp/shared/conn_config.pb volumes: @@ -13,8 +13,8 @@ services: build: context: . dockerfile: Dockerfile + command: ["proxy", "--mlmd-hostname", "localhost", "--mlmd-port", "9090"] container_name: model-registry - ports: - - "8081:8080" + network_mode: host depends_on: - - ml-metadata \ No newline at end of file + - mlmd-server \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index de19a7ee..69822807 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,19 +1,18 @@ version: '3' services: - ml-metadata: + mlmd-server: image: gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0 container_name: mlmd-server ports: - - "8080:8080" + - "9090:8080" environment: - METADATA_STORE_SERVER_CONFIG_FILE=/tmp/shared/conn_config.pb volumes: - ./test/config/ml-metadata:/tmp/shared model-registry: image: quay.io/opendatahub/model-registry:latest - command: ["proxy"] + command: ["proxy", "--mlmd-hostname", "localhost", "--mlmd-port", "9090"] container_name: model-registry - ports: - - "8081:8080" + network_mode: host depends_on: - - ml-metadata \ No newline at end of file + - mlmd-server \ No newline at end of file From 8005f079889794b19e910764835725a1a388d757 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 16 Nov 2023 08:57:22 +0100 Subject: [PATCH 129/254] Update build-image-pr.yml: swich to pull_request event (#153) --- .github/workflows/build-image-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index 562545a5..8fe7f01b 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -1,7 +1,7 @@ name: Test container image build on: - pull_request_target: + pull_request: paths-ignore: - 'LICENSE*' - '**.gitignore' From 9ed849dc4ac060451b937ec639c4de2dc43d39fa Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 16 Nov 2023 09:31:18 +0100 Subject: [PATCH 130/254] Fix core library issue (#154) * Manage *ByParams errors * Fix runtime movement to inference service * Add mapper test --- .../converter/mlmd_openapi_converter_util.go | 4 +- internal/mapper/mapper.go | 24 +-- internal/mapper/mapper_test.go | 147 ++++++++++++++++++ pkg/core/core.go | 32 +++- pkg/core/core_test.go | 25 ++- 5 files changed, 199 insertions(+), 33 deletions(-) create mode 100644 internal/mapper/mapper_test.go diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 44d206b1..cb22e248 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -78,10 +78,10 @@ func MapNameFromOwned(source *string) *string { // MODEL ARTIFACT func MapArtifactType(source *proto.Artifact) (string, error) { - if *source.Type == ModelArtifactTypeName { + if source.Type != nil && *source.Type == ModelArtifactTypeName { return "model-artifact", nil } - return "", fmt.Errorf("invalid artifact type found") + return "", fmt.Errorf("invalid artifact type found: %v", source.Type) } func MapMLMDModelArtifactState(source *proto.Artifact_State) *openapi.ArtifactState { diff --git a/internal/mapper/mapper.go b/internal/mapper/mapper.go index cff7f23d..865c48d8 100644 --- a/internal/mapper/mapper.go +++ b/internal/mapper/mapper.go @@ -131,27 +131,15 @@ func (m *Mapper) MapFromServeModel(serveModel *openapi.ServeModel, inferenceServ // Utilities for MLMD --> OpenAPI mapping, make use of generated Converters func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredModel, error) { - if ctx.GetTypeId() != m.RegisteredModelTypeId { - return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", m.RegisteredModelTypeId, ctx.GetTypeId()) - } - - return m.MLMDConverter.ConvertRegisteredModel(ctx) + return mapTo(ctx, m.RegisteredModelTypeId, m.MLMDConverter.ConvertRegisteredModel) } func (m *Mapper) MapToModelVersion(ctx *proto.Context) (*openapi.ModelVersion, error) { - if ctx.GetTypeId() != m.ModelVersionTypeId { - return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", m.ModelVersionTypeId, ctx.GetTypeId()) - } - - return m.MLMDConverter.ConvertModelVersion(ctx) + return mapTo(ctx, m.ModelVersionTypeId, m.MLMDConverter.ConvertModelVersion) } -func (m *Mapper) MapToModelArtifact(artifact *proto.Artifact) (*openapi.ModelArtifact, error) { - if artifact.GetTypeId() != m.ModelArtifactTypeId { - return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", m.ModelArtifactTypeId, artifact.GetTypeId()) - } - - return m.MLMDConverter.ConvertModelArtifact(artifact) +func (m *Mapper) MapToModelArtifact(art *proto.Artifact) (*openapi.ModelArtifact, error) { + return mapTo(art, m.ModelArtifactTypeId, m.MLMDConverter.ConvertModelArtifact) } func (m *Mapper) MapToServingEnvironment(ctx *proto.Context) (*openapi.ServingEnvironment, error) { @@ -162,8 +150,8 @@ func (m *Mapper) MapToInferenceService(ctx *proto.Context) (*openapi.InferenceSe return mapTo(ctx, m.InferenceServiceTypeId, m.MLMDConverter.ConvertInferenceService) } -func (m *Mapper) MapToServeModel(ctx *proto.Execution) (*openapi.ServeModel, error) { - return mapTo(ctx, m.ServeModelTypeId, m.MLMDConverter.ConvertServeModel) +func (m *Mapper) MapToServeModel(ex *proto.Execution) (*openapi.ServeModel, error) { + return mapTo(ex, m.ServeModelTypeId, m.MLMDConverter.ConvertServeModel) } type getTypeIder interface { diff --git a/internal/mapper/mapper_test.go b/internal/mapper/mapper_test.go new file mode 100644 index 00000000..4174ff84 --- /dev/null +++ b/internal/mapper/mapper_test.go @@ -0,0 +1,147 @@ +package mapper + +import ( + "fmt" + "testing" + + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/stretchr/testify/assert" +) + +const ( + invalidTypeId = int64(9999) + registeredModelTypeId = int64(1) + modelVersionTypeId = int64(2) + modelArtifactTypeId = int64(3) + servingEnvironmentTypeId = int64(4) + inferenceServiceTypeId = int64(5) + serveModelTypeId = int64(6) +) + +func setup(t *testing.T) (*assert.Assertions, *Mapper) { + return assert.New(t), NewMapper( + registeredModelTypeId, + modelVersionTypeId, + modelArtifactTypeId, + servingEnvironmentTypeId, + inferenceServiceTypeId, + serveModelTypeId, + ) +} + +func TestMapToRegisteredModel(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToRegisteredModel(&proto.Context{ + TypeId: of(registeredModelTypeId), + }) + assertion.Nil(err) +} + +func TestMapToRegisteredModelInvalid(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToRegisteredModel(&proto.Context{ + TypeId: of(invalidTypeId), + }) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", registeredModelTypeId, invalidTypeId), err.Error()) +} + +func TestMapToModelVersion(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToModelVersion(&proto.Context{ + TypeId: of(modelVersionTypeId), + }) + assertion.Nil(err) +} + +func TestMapToModelVersionInvalid(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToModelVersion(&proto.Context{ + TypeId: of(invalidTypeId), + }) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", modelVersionTypeId, invalidTypeId), err.Error()) +} + +func TestMapToModelArtifact(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToModelArtifact(&proto.Artifact{ + TypeId: of(modelArtifactTypeId), + Type: of("odh.ModelArtifact"), + }) + assertion.Nil(err) +} + +func TestMapToModelArtifactMissingType(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToModelArtifact(&proto.Artifact{ + TypeId: of(modelArtifactTypeId), + }) + assertion.NotNil(err) + assertion.Equal("error setting field ArtifactType: invalid artifact type found: ", err.Error()) +} + +func TestMapToModelArtifactInvalid(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToModelArtifact(&proto.Artifact{ + TypeId: of(invalidTypeId), + }) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", modelArtifactTypeId, invalidTypeId), err.Error()) +} + +func TestMapToServingEnvironment(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToServingEnvironment(&proto.Context{ + TypeId: of(servingEnvironmentTypeId), + }) + assertion.Nil(err) +} + +func TestMapToServingEnvironmentInvalid(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToServingEnvironment(&proto.Context{ + TypeId: of(invalidTypeId), + }) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", servingEnvironmentTypeId, invalidTypeId), err.Error()) +} + +func TestMapToInferenceService(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToInferenceService(&proto.Context{ + TypeId: of(inferenceServiceTypeId), + }) + assertion.Nil(err) +} + +func TestMapToInferenceServiceInvalid(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToInferenceService(&proto.Context{ + TypeId: of(invalidTypeId), + }) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", inferenceServiceTypeId, invalidTypeId), err.Error()) +} + +func TestMapToServeModel(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToServeModel(&proto.Execution{ + TypeId: of(serveModelTypeId), + }) + assertion.Nil(err) +} + +func TestMapToServeModelInvalid(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToServeModel(&proto.Execution{ + TypeId: of(invalidTypeId), + }) + assertion.NotNil(err) + assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", serveModelTypeId, invalidTypeId), err.Error()) +} + +// of returns a pointer to the provided literal/const input +func of[E any](e E) *E { + return &e +} diff --git a/pkg/core/core.go b/pkg/core/core.go index 709b1218..7c675abe 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -89,6 +89,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, "registered_model_id": proto.PropertyType_INT, // same information tracked using ParentContext association "serving_environment_id": proto.PropertyType_INT, + "runtime": proto.PropertyType_STRING, }, }, } @@ -99,7 +100,6 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, Properties: map[string]proto.PropertyType{ "description": proto.PropertyType_STRING, "model_version_id": proto.PropertyType_INT, - "runtime": proto.PropertyType_STRING, }, }, } @@ -285,8 +285,12 @@ func (serv *modelRegistryService) GetRegisteredModelByParams(name *string, exter return nil, err } - if len(getByParamsResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple registered models found for name=%v, externalId=%v", *name, *externalId) + if len(getByParamsResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple registered models found for name=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(externalId)) + } + + if len(getByParamsResp.Contexts) == 0 { + return nil, fmt.Errorf("no registered models found for name=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(externalId)) } regModel, err := serv.mapper.MapToRegisteredModel(getByParamsResp.Contexts[0]) @@ -506,10 +510,14 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p return nil, err } - if len(getByParamsResp.Contexts) != 1 { + if len(getByParamsResp.Contexts) > 1 { return nil, fmt.Errorf("multiple model versions found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(versionName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) } + if len(getByParamsResp.Contexts) == 0 { + return nil, fmt.Errorf("no model versions found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(versionName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + } + modelVer, err := serv.mapper.MapToModelVersion(getByParamsResp.Contexts[0]) if err != nil { return nil, err @@ -848,8 +856,12 @@ func (serv *modelRegistryService) GetServingEnvironmentByParams(name *string, ex return nil, err } - if len(getByParamsResp.Contexts) != 1 { - return nil, fmt.Errorf("could not find exactly one Context matching criteria: %v", getByParamsResp.Contexts) + if len(getByParamsResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple serving environments found for name=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(externalId)) + } + + if len(getByParamsResp.Contexts) == 0 { + return nil, fmt.Errorf("no serving environments found for name=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(externalId)) } openapiModel, err := serv.mapper.MapToServingEnvironment(getByParamsResp.Contexts[0]) @@ -1052,8 +1064,12 @@ func (serv *modelRegistryService) GetInferenceServiceByParams(name *string, pare return nil, err } - if len(getByParamsResp.Contexts) != 1 { - return nil, fmt.Errorf("multiple InferenceServices found for name=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + if len(getByParamsResp.Contexts) > 1 { + return nil, fmt.Errorf("multiple inference services found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + } + + if len(getByParamsResp.Contexts) == 0 { + return nil, fmt.Errorf("no inference services found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) } toReturn, err := serv.mapper.MapToInferenceService(getByParamsResp.Contexts[0]) diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index 7187837e..51892818 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -1141,10 +1141,14 @@ func TestCreateModelArtifact(t *testing.T) { modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ - Name: &artifactName, - State: (*openapi.ArtifactState)(&artifactState), - Uri: &artifactUri, - Description: &artifactDescription, + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + Description: &artifactDescription, + ModelFormatName: of("onnx"), + ModelFormatVersion: of("1"), + StorageKey: of("aws-connection-models"), + StoragePath: of("bucket"), CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -1163,6 +1167,10 @@ func TestCreateModelArtifact(t *testing.T) { assertion.Equal(*state, *createdArtifact.State) assertion.Equal(artifactUri, *createdArtifact.Uri) assertion.Equal(artifactDescription, *createdArtifact.Description) + assertion.Equal("onnx", *createdArtifact.ModelFormatName) + assertion.Equal("1", *createdArtifact.ModelFormatVersion) + assertion.Equal("aws-connection-models", *createdArtifact.StorageKey) + assertion.Equal("bucket", *createdArtifact.StoragePath) assertion.Equal(author, *(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue) createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) @@ -1176,6 +1184,10 @@ func TestCreateModelArtifact(t *testing.T) { assertion.Equal(string(*createdArtifact.State), getById.Artifacts[0].State.String()) assertion.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) assertion.Equal(*createdArtifact.Description, getById.Artifacts[0].Properties["description"].GetStringValue()) + assertion.Equal(*createdArtifact.ModelFormatName, getById.Artifacts[0].Properties["model_format_name"].GetStringValue()) + assertion.Equal(*createdArtifact.ModelFormatVersion, getById.Artifacts[0].Properties["model_format_version"].GetStringValue()) + assertion.Equal(*createdArtifact.StorageKey, getById.Artifacts[0].Properties["storage_key"].GetStringValue()) + assertion.Equal(*createdArtifact.StoragePath, getById.Artifacts[0].Properties["storage_path"].GetStringValue()) assertion.Equal(*(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["author"].GetStringValue()) modelVersionIdAsInt, _ := converter.StringToInt64(&modelVersionId) @@ -1937,6 +1949,7 @@ func TestCreateInferenceService(t *testing.T) { parentResourceId := registerServingEnvironment(assertion, service, nil, nil) registeredModelId := registerModel(assertion, service, nil, nil) + runtime := "model-server" eut := &openapi.InferenceService{ Name: &entityName, @@ -1944,6 +1957,7 @@ func TestCreateInferenceService(t *testing.T) { Description: &entityDescription, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, + Runtime: &runtime, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -1954,7 +1968,7 @@ func TestCreateInferenceService(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + assertion.Nilf(err, "error creating new eut for %s: %v", parentResourceId, err) assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") @@ -1973,6 +1987,7 @@ func TestCreateInferenceService(t *testing.T) { assertion.Equal(entityExternalId2, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") assertion.Equal(entityDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") + assertion.Equal(runtime, byId.Contexts[0].Properties["runtime"].GetStringValue(), "saved runtime should match the provided one") assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) From 5a98a6ba2314f5a2f2f7b9367e336c358b4aa8bd Mon Sep 17 00:00:00 2001 From: Radim Kubis Date: Fri, 17 Nov 2023 09:50:25 +0100 Subject: [PATCH 131/254] Revert "Update(Dockerfile): Use ubi9 images that contains required glibc version by gqlgen (#135)" (#150) This reverts commit 6595e84e5c8f342321f97d8cfae63e75997020d3. --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5c8f7303..952fe408 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build the model-registry binary -FROM registry.access.redhat.com/ubi9/go-toolset:1.20 as builder +FROM registry.access.redhat.com/ubi8/go-toolset:1.19 as builder WORKDIR /workspace # Copy the Go Modules manifests @@ -38,7 +38,7 @@ RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 make clean model-registry # Use distroless as minimal base image to package the model-registry binary # Refer to https://github.com/GoogleContainerTools/distroless for more details -FROM registry.access.redhat.com/ubi9/ubi-minimal:9.3 +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 WORKDIR / # copy the metadata library COPY --from=builder /workspace/config ./config From 3e286f3db1bdf18faf928d62c59da3f97720c4d6 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 17 Nov 2023 10:14:14 +0100 Subject: [PATCH 132/254] Remove go-server code from repository (#155) --- Dockerfile | 5 +- Makefile | 37 +- api/graphql/base-schema.graphqls | 175 - api/graphql/ml-metadata.graphqls | 99 - api/graphql/schema.graphqls | 25 - cmd/migrate.go | 144 - cmd/serve.go | 191 - .../metadata-library/ml-metadata-library.yaml | 14 - .../mlschema-metadata-library.yaml | 27 - go.mod | 25 +- go.sum | 48 - gqlgen.yml | 91 - .../converter/generated/grpc_converter.gen.go | 409 - internal/converter/grpc_converter.go | 84 - internal/converter/grpc_converter_util.go | 371 - .../converter/grpc_converter_util_test.go | 876 - internal/model/db/artifact.go | 52 - internal/model/db/artifactproperty.go | 102 - internal/model/db/association.go | 17 - internal/model/db/attribution.go | 17 - internal/model/db/context.go | 28 - internal/model/db/contextproperty.go | 102 - internal/model/db/event.go | 39 - internal/model/db/eventpath.go | 16 - internal/model/db/execution.go | 37 - internal/model/db/executionproperty.go | 102 - internal/model/db/mlmdenv.go | 13 - internal/model/db/parentcontext.go | 14 - internal/model/db/parenttype.go | 14 - internal/model/db/property_interface.go | 24 - internal/model/db/type.go | 32 - internal/model/db/typeproperty.go | 15 - internal/model/graph/models_gen.go | 562 - internal/model/library/metadata_library.go | 100 - internal/model/library/propertytype_enum.go | 271 - .../server/graph/base-schema.resolvers.go | 22 - internal/server/graph/generated.go | 15612 ---------------- internal/server/graph/resolver.go | 7 - internal/server/graph/schema.resolvers.go | 65 - internal/server/grpc/grpc_server.go | 591 - internal/service/artifact_handler.go | 9 - internal/service/db_context.go | 85 - internal/service/db_service.go | 39 - internal/service/db_service_test.go | 146 - internal/service/type_handler.go | 64 - tools.go | 11 - 46 files changed, 10 insertions(+), 20819 deletions(-) delete mode 100644 api/graphql/base-schema.graphqls delete mode 100644 api/graphql/ml-metadata.graphqls delete mode 100644 api/graphql/schema.graphqls delete mode 100644 cmd/migrate.go delete mode 100644 cmd/serve.go delete mode 100644 config/metadata-library/ml-metadata-library.yaml delete mode 100644 config/metadata-library/mlschema-metadata-library.yaml delete mode 100644 gqlgen.yml delete mode 100755 internal/converter/generated/grpc_converter.gen.go delete mode 100644 internal/converter/grpc_converter.go delete mode 100644 internal/converter/grpc_converter_util.go delete mode 100644 internal/converter/grpc_converter_util_test.go delete mode 100644 internal/model/db/artifact.go delete mode 100644 internal/model/db/artifactproperty.go delete mode 100644 internal/model/db/association.go delete mode 100644 internal/model/db/attribution.go delete mode 100644 internal/model/db/context.go delete mode 100644 internal/model/db/contextproperty.go delete mode 100644 internal/model/db/event.go delete mode 100644 internal/model/db/eventpath.go delete mode 100644 internal/model/db/execution.go delete mode 100644 internal/model/db/executionproperty.go delete mode 100644 internal/model/db/mlmdenv.go delete mode 100644 internal/model/db/parentcontext.go delete mode 100644 internal/model/db/parenttype.go delete mode 100644 internal/model/db/property_interface.go delete mode 100644 internal/model/db/type.go delete mode 100644 internal/model/db/typeproperty.go delete mode 100644 internal/model/graph/models_gen.go delete mode 100644 internal/model/library/metadata_library.go delete mode 100644 internal/model/library/propertytype_enum.go delete mode 100644 internal/server/graph/base-schema.resolvers.go delete mode 100644 internal/server/graph/generated.go delete mode 100644 internal/server/graph/resolver.go delete mode 100644 internal/server/graph/schema.resolvers.go delete mode 100644 internal/server/grpc/grpc_server.go delete mode 100644 internal/service/artifact_handler.go delete mode 100644 internal/service/db_context.go delete mode 100644 internal/service/db_service.go delete mode 100644 internal/service/db_service_test.go delete mode 100644 internal/service/type_handler.go delete mode 100644 tools.go diff --git a/Dockerfile b/Dockerfile index 952fe408..243f81db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ USER root RUN yum install -y nodejs npm java-11 # Copy the go source -COPY ["Makefile", "main.go", "gqlgen.yml", ".openapi-generator-ignore", "openapitools.json", "./"] +COPY ["Makefile", "main.go", ".openapi-generator-ignore", "openapitools.json", "./"] # Download protoc compiler v24.3 RUN wget -q https://github.com/protocolbuffers/protobuf/releases/download/v24.3/protoc-24.3-linux-x86_64.zip -O protoc.zip && \ @@ -28,7 +28,6 @@ RUN make deps COPY bin/ bin/ COPY cmd/ cmd/ COPY api/ api/ -COPY config/ config/ COPY internal/ internal/ COPY pkg/ pkg/ @@ -40,8 +39,6 @@ RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 make clean model-registry # Refer to https://github.com/GoogleContainerTools/distroless for more details FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 WORKDIR / -# copy the metadata library -COPY --from=builder /workspace/config ./config # copy the registry binary COPY --from=builder /workspace/model-registry . USER 65532:65532 diff --git a/Makefile b/Makefile index 9bbcaa75..8cf4b62a 100644 --- a/Makefile +++ b/Makefile @@ -62,13 +62,7 @@ internal/converter/generated/converter.go: internal/converter/*.go goverter gen github.com/opendatahub-io/model-registry/internal/converter/ .PHONY: gen/converter -gen/converter: gen/grpc internal/converter/generated/converter.go gen/graph - -.PHONY: gen/graph -gen/graph: internal/model/graph/models_gen.go - -internal/model/graph/models_gen.go: api/graphql/*.graphqls gqlgen.yml - gqlgen generate +gen/converter: gen/grpc internal/converter/generated/converter.go # validate the openapi schema .PHONY: openapi/validate @@ -103,7 +97,7 @@ vet: .PHONY: clean clean: - rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/model/graph/models_gen.go internal/converter/generated/*.go pkg/openapi + rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/converter/generated/*.go pkg/openapi bin/go-enum: GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 @@ -114,9 +108,6 @@ bin/protoc-gen-go: bin/protoc-gen-go-grpc: GOBIN=$(PROJECT_BIN) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 -bin/gqlgen: - GOBIN=$(PROJECT_BIN) go install github.com/99designs/gqlgen@v0.17.36 - bin/golangci-lint: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.54.2 @@ -146,7 +137,7 @@ clean/deps: rm -Rf bin/* .PHONY: deps -deps: bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/gqlgen bin/golangci-lint bin/goverter bin/openapi-generator-cli +deps: bin/go-enum bin/protoc-gen-go bin/protoc-gen-go-grpc bin/golangci-lint bin/goverter bin/openapi-generator-cli .PHONY: vendor vendor: @@ -157,7 +148,7 @@ build: gen vet lint go build .PHONY: gen -gen: deps gen/grpc gen/openapi gen/converter gen/graph +gen: deps gen/grpc gen/openapi gen/converter go generate ./... .PHONY: lint @@ -177,27 +168,13 @@ test-nocache: gen test-cover: gen go test ./internal/... ./pkg/... -cover -count=1 -.PHONY: run/migrate -run/migrate: gen - go run main.go migrate --logtostderr=true -m config/metadata-library - -metadata.sqlite.db: run/migrate - -.PHONY: run/server -run/server: gen metadata.sqlite.db - go run main.go serve --logtostderr=true - .PHONY: run/proxy run/proxy: gen go run main.go proxy --logtostderr=true -.PHONY: run/client -run/client: gen - python test/python/test_mlmetadata.py - -.PHONY: serve -serve: build - ./model-registry serve --logtostderr=true +.PHONY: proxy +proxy: build + ./model-registry proxy --logtostderr=true # login to docker .PHONY: docker/login diff --git a/api/graphql/base-schema.graphqls b/api/graphql/base-schema.graphqls deleted file mode 100644 index f615aed3..00000000 --- a/api/graphql/base-schema.graphqls +++ /dev/null @@ -1,175 +0,0 @@ -type Artifact { - id: ID - typeId: ID! - uri: String! - state: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type(filter: InstanceFilter): ArtifactType! - properties : [ArtifactProperty!] -} - -type ArtifactProperty { - artifactId: ID - name: String - isCustomProperty: Boolean! - propertyValue: Value! -} - -type Context { - id: ID - typeId: ID! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ContextType! - parent: Context - children: [Context] - attributions: [Artifact!] - associations: [Execution!] - properties: [ContextProperty!] -} - -type ContextProperty { - contextId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} - -type Event { - id: ID - artifactId: ID! - executionId: ID! - type: Int! - artifact: Artifact - execution: Execution - millisecondsSinceEpoch: Int! -} - -type EventPath { - eventId: ID! - isIndexStep: Int! - stepIndex: Int! - stepKey: String! -} - -type Execution { - id: ID - typeId: ID! - lastKnownState: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ExecutionType! - properties: [ExecutionProperty!] -} - -type ExecutionProperty { - executionId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} - -union Value = IntValue | DoubleValue | StringValue | BoolValue - -type IntValue { - value: Int! -} - -type DoubleValue { - value: Float! -} - -type StringValue { - value: String! -} - -type BoolValue { - value: Boolean! -} - -interface Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type TypeProperty { - typeId: ID! - name: String! - dataType: Int! -} - -interface ArtifactTypeInterface implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type ArtifactType implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -interface ContextTypeInterface implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type ContextType implements ContextTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -interface ExecutionTypeInterface implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type ExecutionType implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} diff --git a/api/graphql/ml-metadata.graphqls b/api/graphql/ml-metadata.graphqls deleted file mode 100644 index 2531754a..00000000 --- a/api/graphql/ml-metadata.graphqls +++ /dev/null @@ -1,99 +0,0 @@ -type MlmdDataset implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdModel implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdMetrics implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdStatistics implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdTrain implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdTransform implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdProcess implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdEvaluate implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdDeploy implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} diff --git a/api/graphql/schema.graphqls b/api/graphql/schema.graphqls deleted file mode 100644 index 945a9f87..00000000 --- a/api/graphql/schema.graphqls +++ /dev/null @@ -1,25 +0,0 @@ -input TypeFilter { - ids: [ID!] - names: [String!] - versions: [String!] - externalIds: [String!] -} - -input InstanceFilter { - ids: [ID!] - typeIds: [ID!] - names: [String!] - externalIds: [String!] -} - -type Query { - types(filter: TypeFilter): [Type!] - artifactTypes(filter: TypeFilter): [ArtifactType!] - contextTypes(filter: TypeFilter): [ContextType!] - executionTypes(filter: TypeFilter): [ExecutionType!] - artifacts(filter: InstanceFilter): [Artifact!] - contexts(filter: InstanceFilter): [Context!] - executions(filter: InstanceFilter): [Execution!] - events: [Event!] - mlmdDataset(filter: InstanceFilter): [MlmdDataset!] -} diff --git a/cmd/migrate.go b/cmd/migrate.go deleted file mode 100644 index 66b15cdd..00000000 --- a/cmd/migrate.go +++ /dev/null @@ -1,144 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - "github.com/golang/glog" - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/db" - "github.com/opendatahub-io/model-registry/internal/model/library" - "github.com/opendatahub-io/model-registry/internal/server/grpc" - "github.com/spf13/cobra" - "gorm.io/gorm" -) - -// migrateCmd represents the migrate command -var migrateCmd = &cobra.Command{ - Use: "migrate", - Short: "Migrate ml-metadata DB to latest schema", - Long: `This command migrates an existing DB to the latest schema -used by model-registry. It can also create a new DB if it doesn't exist. - -This command can create a new ml-metadata Sqlite DB, or migrate an existing DB -to the latest schema required by this server.`, - RunE: func(cmd *cobra.Command, args []string) error { - // connect to DB - dbConn, err := NewDatabaseConnection(cfg.DbFile) - defer func() { - // close DB connection on exit - db, err2 := dbConn.DB() - if err2 != nil { - err2 = db.Close() - if err2 != nil { - glog.Warningf("error closing DB connection: %v", err2) - } - } - }() - if err != nil { - return fmt.Errorf("db connection failed: %w", err) - } - // migrate all DB types - err = migrateDatabase(dbConn) - if err != nil { - return err - } - - // load metadata type libraries - err = loadLibraries(dbConn) - if err != nil { - return err - } - return nil - }, -} - -func migrateDatabase(dbConn *gorm.DB) error { - // TODO add support for more elaborate Gorm migrations - err := dbConn.AutoMigrate( - db.Artifact{}, - db.ArtifactProperty{}, - db.Association{}, - db.Attribution{}, - db.Context{}, - db.ContextProperty{}, - db.Event{}, - db.EventPath{}, - db.Execution{}, - db.ExecutionProperty{}, - db.ParentContext{}, - db.Type{}, - db.TypeProperty{}, - ) - if err != nil { - return fmt.Errorf("db migration failed: %w", err) - } - return nil -} - -func loadLibraries(dbConn *gorm.DB) error { - libs, err := library.LoadLibraries(cfg.LibraryDirs) - if err != nil { - return fmt.Errorf("failed to read library directories %s: %w", cfg.LibraryDirs, err) - } - for path, lib := range libs { - grpcServer := grpc.NewGrpcServer(dbConn) - typesRequest := proto.PutTypesRequest{} - for _, at := range lib.ArtifactTypes { - typesRequest.ArtifactTypes = append(typesRequest.ArtifactTypes, &proto.ArtifactType{ - Name: at.Name, - Version: at.Version, - Description: at.Description, - ExternalId: at.ExternalId, - Properties: ToProtoProperties(at.Properties), - }) - } - for _, ct := range lib.ContextTypes { - typesRequest.ContextTypes = append(typesRequest.ContextTypes, &proto.ContextType{ - Name: ct.Name, - Version: ct.Version, - Description: ct.Description, - ExternalId: ct.ExternalId, - Properties: ToProtoProperties(ct.Properties), - }) - } - for _, et := range lib.ExecutionTypes { - typesRequest.ExecutionTypes = append(typesRequest.ExecutionTypes, &proto.ExecutionType{ - Name: et.Name, - Version: et.Version, - Description: et.Description, - ExternalId: et.ExternalId, - Properties: ToProtoProperties(et.Properties), - }) - } - response, err := grpcServer.PutTypes(context.Background(), &typesRequest) - if err != nil { - return fmt.Errorf("failed to add library from file %s: %w", path, err) - } - glog.Infof("created/updated %d ArtifactTypes, %d ContextTypes and %d ExecutionTypes from library file %s", - len(response.ArtifactTypeIds), len(response.ContextTypeIds), len(response.ExecutionTypeIds), path) - } - return nil -} - -func ToProtoProperties(props map[string]library.PropertyType) map[string]proto.PropertyType { - result := make(map[string]proto.PropertyType) - for name, prop := range props { - result[name] = proto.PropertyType(prop) - } - return result -} - -func init() { - rootCmd.AddCommand(migrateCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // migrateCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - migrateCmd.Flags().StringVarP(&cfg.DbFile, "db-file", "d", cfg.DbFile, "Sqlite DB file") - migrateCmd.Flags().StringSliceVarP(&cfg.LibraryDirs, "metadata-library-dir", "m", cfg.LibraryDirs, "Built-in metadata types library directories containing yaml files") -} diff --git a/cmd/serve.go b/cmd/serve.go deleted file mode 100644 index a494079f..00000000 --- a/cmd/serve.go +++ /dev/null @@ -1,191 +0,0 @@ -package cmd - -import ( - "context" - "fmt" - grpc2 "github.com/opendatahub-io/model-registry/internal/server/grpc" - "log" - "net" - "net/http" - "os" - "os/signal" - "syscall" - - "github.com/99designs/gqlgen/graphql/handler" - "github.com/99designs/gqlgen/graphql/playground" - "github.com/golang/glog" - "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/logging" - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/server/graph" - "github.com/soheilhy/cmux" - "github.com/spf13/cobra" - "golang.org/x/sync/errgroup" - "google.golang.org/grpc" - "google.golang.org/grpc/health" - "google.golang.org/grpc/health/grpc_health_v1" - "google.golang.org/grpc/reflection" - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -func InterceptorLogger(l *log.Logger) logging.Logger { - return logging.LoggerFunc(func(_ context.Context, lvl logging.Level, msg string, fields ...any) { - switch lvl { - case logging.LevelDebug: - msg = fmt.Sprintf("DEBUG :%v", msg) - case logging.LevelInfo: - msg = fmt.Sprintf("INFO :%v", msg) - case logging.LevelWarn: - msg = fmt.Sprintf("WARN :%v", msg) - case logging.LevelError: - msg = fmt.Sprintf("ERROR :%v", msg) - default: - panic(fmt.Sprintf("unknown level %v", lvl)) - } - l.Println(append([]any{"msg", msg}, fields...)) - }) -} - -var ( - // serveCmd represents the serve command - serveCmd = &cobra.Command{ - Use: "serve", - Short: "Starts the ml-metadata go server", - Long: `This command launches the ml-metadata go server. - -The server connects to a SQlite database. It supports options to customize the -location of the database file and the hostname and port where it listens.'`, - RunE: runServer, - } -) - -func runServer(cmd *cobra.Command, args []string) error { - glog.Infof("server started at %s:%v", cfg.Hostname, cfg.Port) - - // Create a channel to receive signals - signalChannel := make(chan os.Signal, 1) - - // Notify the channel on SIGINT (Ctrl+C) and SIGTERM signals - signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM) - - // connect to the DB using Gorm - db, err := NewDatabaseConnection(cfg.DbFile) - if err != nil { - log.Fatalf("db connection failed: %v", err) - } - - // listen on host:port - listener, err := net.Listen("tcp", fmt.Sprintf("%s:%d", cfg.Hostname, cfg.Port)) - if err != nil { - log.Fatalf("server listen failed: %v", err) - } - m := cmux.New(listener) - gqlListener := m.Match(cmux.HTTP1Fast()) - grpcListener := m.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings("content-type", "application/grpc")) - - // gRPC server - grpcServer := grpcListenerServer(grpc2.NewGrpcServer(db)) - // GraphQL server - gqlServer := graphQlListenerServer(db) - - // start cmux listeners - g := new(errgroup.Group) - g.Go(func() error { - glog.Info("starting gRPC server...") - return grpcServer.Serve(grpcListener) - }) - g.Go(func() error { - glog.Info("starting GraphQL server...") - return gqlServer.Serve(gqlListener) - }) - g.Go(func() error { - return m.Serve() - }) - - go func() { - err = g.Wait() - // error starting server - if err != nil || err != http.ErrServerClosed || err != grpc.ErrServerStopped || err != cmux.ErrServerClosed { - glog.Errorf("server listener error: %v", err) - } - signalChannel <- syscall.SIGINT - }() - - // Wait for a signal - receivedSignal := <-signalChannel - glog.Infof("received signal: %s\n", receivedSignal) - - // Perform cleanup or other graceful shutdown actions here - glog.Info("shutting down services...") - grpcServer.Stop() - _ = gqlServer.Shutdown(context.Background()) - - // close DB - glog.Info("closing DB...") - sqlDB, err := db.DB() - if err != nil { - return fmt.Errorf("error accessing DB: %v", err) - } - err = sqlDB.Close() - if err != nil { - return fmt.Errorf("error closing DB: %v", err) - } - glog.Info("shutdown!") - return nil -} - -func graphQlListenerServer(db *gorm.DB) *http.Server { - mux := http.NewServeMux() - srv := handler.NewDefaultServer(graph.NewExecutableSchema(graph.Config{Resolvers: &graph.Resolver{}})) - - mux.Handle("/", playground.Handler("GraphQL playground", "/query")) - mux.Handle("/query", srv) - - return &http.Server{Handler: mux} -} - -func grpcListenerServer(server proto.MetadataStoreServiceServer) *grpc.Server { - // TODO map server options from flags - logger := log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile) - lopts := []logging.Option{ - logging.WithLogOnEvents(logging.PayloadReceived, logging.PayloadSent, logging.StartCall, logging.FinishCall), - // Add any other option (check functions starting with logging.With). - } - opts := []grpc.ServerOption{ - grpc.ChainUnaryInterceptor( - logging.UnaryServerInterceptor(InterceptorLogger(logger), lopts...), - ), - grpc.ChainStreamInterceptor( - logging.StreamServerInterceptor(InterceptorLogger(logger), lopts...), - ), - } - - grpcServer := grpc.NewServer(opts...) - // simple health check - grpc_health_v1.RegisterHealthServer(grpcServer, health.NewServer()) - - proto.RegisterMetadataStoreServiceServer(grpcServer, server) - reflection.Register(grpcServer) - - return grpcServer -} - -func NewDatabaseConnection(dbFile string) (*gorm.DB, error) { - return gorm.Open(sqlite.Open(dbFile), &gorm.Config{}) -} - -func init() { - rootCmd.AddCommand(serveCmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // serveCmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - serveCmd.Flags().StringVarP(&cfg.DbFile, "db-file", "d", cfg.DbFile, "Sqlite DB file") - serveCmd.Flags().StringVarP(&cfg.Hostname, "hostname", "n", cfg.Hostname, "Server listen hostname") - serveCmd.Flags().IntVarP(&cfg.Port, "port", "p", cfg.Port, "Server listen port") -} diff --git a/config/metadata-library/ml-metadata-library.yaml b/config/metadata-library/ml-metadata-library.yaml deleted file mode 100644 index 991a62a4..00000000 --- a/config/metadata-library/ml-metadata-library.yaml +++ /dev/null @@ -1,14 +0,0 @@ -# types for ml-metadata library -artifact-types: - - name: "mlmd.Dataset" - properties: - "note": STRING - - name: "mlmd.Model" - - name: "mlmd.Metrics" - - name: "mlmd.Statistics" -execution-types: - - name: "mlmd.Train" - - name: "mlmd.Transform" - - name: "mlmd.Process" - - name: "mlmd.Evaluate" - - name: "mlmd.Deploy" diff --git a/config/metadata-library/mlschema-metadata-library.yaml b/config/metadata-library/mlschema-metadata-library.yaml deleted file mode 100644 index 6fa21269..00000000 --- a/config/metadata-library/mlschema-metadata-library.yaml +++ /dev/null @@ -1,27 +0,0 @@ -# types for ml-metadata library -artifact-types: - - name: "mlschema.Model" - - name: "mlschema.ModelEvaluation" - - name: "mlschema.EvaluationMeasure" - - name: "mlschema.EvaluationSpecification" - - name: "mlschema.EvaluationProcedure" - - name: "mlschema.Task" - - name: "mlschema.Data" - - name: "mlschema.DataSet" - - name: "mlschema.Feature" - - name: "mlschema.Algorithm" - - name: "mlschema.Software" - - name: "mlschema.Implementation" - - name: "mlschema.HyperParameter" - - name: "mlschema.HyperParameterSetting" - - name: "mlschema.ImplementationCharacteristic" - - name: "mlschema.DatasetCharacteristic" - - name: "mlschema.FeatureCharacteristic" -context-types: - - name: "mlschema.RegisteredModel" - - name: "mlschema.ModelVersion" - - name: "mlschema.DataCharacteristic" -execution-types: - - name: "mlschema.Study" - - name: "mlschema.Experiment" - - name: "mlschema.Run" diff --git a/go.mod b/go.mod index 6368e09d..62acb005 100644 --- a/go.mod +++ b/go.mod @@ -3,26 +3,16 @@ module github.com/opendatahub-io/model-registry go 1.19 require ( - github.com/99designs/gqlgen v0.17.40 github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/cors v1.2.1 github.com/golang/glog v1.1.2 - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 - github.com/searKing/golang/tools/go-enum v1.2.97 - github.com/soheilhy/cmux v0.1.5 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.17.0 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 - github.com/vektah/gqlparser/v2 v2.5.10 - golang.org/x/sync v0.5.0 google.golang.org/grpc v1.59.0 - google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 google.golang.org/protobuf v1.31.0 - gopkg.in/yaml.v3 v3.0.1 - gorm.io/driver/sqlite v1.5.4 - gorm.io/gorm v1.25.5 ) require ( @@ -37,10 +27,11 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/sosodev/duration v1.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect + golang.org/x/sync v0.5.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) require ( @@ -48,11 +39,9 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.1 // indirect - github.com/agnivade/levenshtein v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/containerd/containerd v1.7.7 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/cucumber/godog v0.13.0 github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.7+incompatible // indirect @@ -63,16 +52,11 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/google/uuid v1.4.0 - github.com/gorilla/websocket v1.5.0 // indirect - github.com/hashicorp/golang-lru/v2 v2.0.3 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect github.com/klauspost/compress v1.17.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/patternmatcher v0.6.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect @@ -84,9 +68,6 @@ require ( github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/searKing/golang/go v1.2.52 // indirect - github.com/searKing/golang/tools v1.2.29 // indirect github.com/shirou/gopsutil/v3 v3.23.9 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect @@ -95,8 +76,6 @@ require ( github.com/subosito/gotenv v1.6.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/urfave/cli/v2 v2.25.5 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/mod v0.12.0 // indirect diff --git a/go.sum b/go.sum index 35f9c9d4..facef6ef 100644 --- a/go.sum +++ b/go.sum @@ -38,8 +38,6 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/99designs/gqlgen v0.17.40 h1:/l8JcEVQ93wqIfmH9VS1jsAkwm6eAF1NwQn3N+SDqBY= -github.com/99designs/gqlgen v0.17.40/go.mod h1:b62q1USk82GYIVjC60h02YguAZLqYZtvWml8KkhJps4= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= @@ -49,11 +47,6 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= -github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= -github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo= -github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= -github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -76,7 +69,6 @@ github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoY github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= @@ -91,8 +83,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g= -github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= @@ -193,10 +183,6 @@ github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1 h1:HcUWd006luQPljE73d5sk+/VgYPGUReEVz2y1/qylwY= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.1/go.mod h1:w9Y7gY31krpLmrVU5ZPG9H7l9fZuRu5/3R3S3FMtVQ4= github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -209,18 +195,12 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/golang-lru/v2 v2.0.3 h1:kmRrRLlInXvng0SmLxmQpQkpbYAvcXm7NPDrgxJa9mE= -github.com/hashicorp/golang-lru/v2 v2.0.3/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= -github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -238,8 +218,6 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= -github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= @@ -274,20 +252,12 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/searKing/golang/go v1.2.52 h1:Nbsr8HIS4ATL7LY1BE3SwRyEQd+UkrRymyol46sXb3s= -github.com/searKing/golang/go v1.2.52/go.mod h1:9AhTd9NFW/ck459PgNJwBA6I5q/ZBt9qOSvv9oZvHgA= -github.com/searKing/golang/tools v1.2.29 h1:gWX4aCA1+N7CfLpNd6tmBjYtecTksZFXziqbQ+AJKLo= -github.com/searKing/golang/tools v1.2.29/go.mod h1:QtwFM73H1qMKlRl0p8NRWXrNaCaffoYkNHk5YMoRyOY= -github.com/searKing/golang/tools/go-enum v1.2.97 h1:mX396oCnjdGqmMmwffBwpEU3L1X/7K3eDuXOOLow+TQ= -github.com/searKing/golang/tools/go-enum v1.2.97/go.mod h1:gWZ/vkIPpA0nCHDMETjzKqsHPDWSPdhZeXPxf/jWyqA= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= @@ -298,10 +268,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/sosodev/duration v1.1.0 h1:kQcaiGbJaIsRqgQy7VGlZrVw1giWO+lDoX3MCPnpVO4= -github.com/sosodev/duration v1.1.0/go.mod h1:RQIBBX0+fMLc/D9+Jb/fwvVmo0eZvDDEERAikUR6SDg= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= @@ -339,14 +305,8 @@ github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0h github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.25.5 h1:d0NIAyhh5shGscroL7ek/Ya9QYQE0KNabJgiUinIQkc= -github.com/urfave/cli/v2 v2.25.5/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= -github.com/vektah/gqlparser/v2 v2.5.10 h1:6zSM4azXC9u4Nxy5YmdmGu4uKamfwsdKTwp5zsEealU= -github.com/vektah/gqlparser/v2 v2.5.10/go.mod h1:1rCcfwB2ekJofmluGWXMSEnPMZgbxzwj6FaZ/4OT8Cc= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -435,7 +395,6 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -667,8 +626,6 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -692,14 +649,9 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/sqlite v1.5.4 h1:IqXwXi8M/ZlPzH/947tn5uik3aYQslP9BVveoax0nV0= -gorm.io/driver/sqlite v1.5.4/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= -gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls= -gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/gqlgen.yml b/gqlgen.yml deleted file mode 100644 index 34decc08..00000000 --- a/gqlgen.yml +++ /dev/null @@ -1,91 +0,0 @@ -# Where are all the schema files located? globs are supported eg src/**/*.graphqls -schema: - - api/graphql/*.graphqls - -# Where should the generated server code go? -exec: - filename: internal/server/graph/generated.go - package: graph - -# Uncomment to enable federation -# federation: -# filename: graph/federation.go -# package: graph - -# Where should any generated models go? -model: - filename: internal/model/graph/models_gen.go - package: graph - -# Where should the resolver implementations go? -resolver: - layout: follow-schema - dir: internal/server/graph - package: graph - filename_template: "{name}.resolvers.go" - # Optional: turn on to not generate template comments above resolvers - # omit_template_comment: false - -# Optional: turn on use ` + "`" + `gqlgen:"fieldName"` + "`" + ` tags in your models -# struct_tag: json - -# Optional: turn on to use []Thing instead of []*Thing -# omit_slice_element_pointers: false - -# Optional: turn on to omit Is() methods to interface and unions -# omit_interface_checks : true - -# Optional: turn on to skip generation of ComplexityRoot struct content and Complexity function -# omit_complexity: false - -# Optional: turn on to not generate any file notice comments in generated files -# omit_gqlgen_file_notice: false - -# Optional: turn on to exclude the gqlgen version in the generated file notice. No effect if `omit_gqlgen_file_notice` is true. -# omit_gqlgen_version_in_file_notice: false - -# Optional: turn off to make struct-type struct fields not use pointers -# e.g. type Thing struct { FieldA OtherThing } instead of { FieldA *OtherThing } -# struct_fields_always_pointers: true - -# Optional: turn off to make resolvers return values instead of pointers for structs -# resolvers_always_return_pointers: true - -# Optional: turn on to return pointers instead of values in unmarshalInput -# return_pointers_in_unmarshalinput: false - -# Optional: wrap nullable input fields with Omittable -# nullable_input_omittable: true - -# Optional: set to speed up generation time by not performing a final validation pass. -# skip_validation: true - -# Optional: set to skip running `go mod tidy` when generating server code -# skip_mod_tidy: true - -# gqlgen will search for any type names in the schema in these go packages -# if they match it will use them, otherwise it will generate them. -autobind: -# - "github.com/opendatahub-io/model-registry/graph/model" - -# This section declares type mapping between the GraphQL and go type systems -# -# The first line in each type will be used as defaults for resolver arguments and -# modelgen, the others will be allowed when binding to fields. Configure them to -# your liking -models: - ID: - model: - - github.com/99designs/gqlgen/graphql.ID - - github.com/99designs/gqlgen/graphql.Int - - github.com/99designs/gqlgen/graphql.Int64 - - github.com/99designs/gqlgen/graphql.Int32 - Int: - model: - - github.com/99designs/gqlgen/graphql.Int - - github.com/99designs/gqlgen/graphql.Int64 - - github.com/99designs/gqlgen/graphql.Int32 - Artifact: - fields: - type: - resolver: true diff --git a/internal/converter/generated/grpc_converter.gen.go b/internal/converter/generated/grpc_converter.gen.go deleted file mode 100755 index 69f285ac..00000000 --- a/internal/converter/generated/grpc_converter.gen.go +++ /dev/null @@ -1,409 +0,0 @@ -// Code generated by github.com/jmattheis/goverter, DO NOT EDIT. - -package generated - -import ( - "fmt" - converter "github.com/opendatahub-io/model-registry/internal/converter" - proto "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - db "github.com/opendatahub-io/model-registry/internal/model/db" -) - -type GRPCConverterImpl struct{} - -func (c *GRPCConverterImpl) ConvertArtifact(source *proto.Artifact) (*db.Artifact, error) { - var pDbArtifact *db.Artifact - if source != nil { - var dbArtifact db.Artifact - var xint64 int64 - if (*source).Id != nil { - xint64 = *(*source).Id - } - dbArtifact.ID = xint64 - var xint642 int64 - if (*source).TypeId != nil { - xint642 = *(*source).TypeId - } - dbArtifact.TypeID = xint642 - var pString *string - if (*source).Uri != nil { - xstring := *(*source).Uri - pString = &xstring - } - dbArtifact.URI = pString - dbArtifact.State = converter.ConvertArtifact_State((*source).State) - var pString2 *string - if (*source).Name != nil { - xstring2 := *(*source).Name - pString2 = &xstring2 - } - dbArtifact.Name = pString2 - var pString3 *string - if (*source).ExternalId != nil { - xstring3 := *(*source).ExternalId - pString3 = &xstring3 - } - dbArtifact.ExternalID = pString3 - var xint643 int64 - if (*source).CreateTimeSinceEpoch != nil { - xint643 = *(*source).CreateTimeSinceEpoch - } - dbArtifact.CreateTimeSinceEpoch = xint643 - var xint644 int64 - if (*source).LastUpdateTimeSinceEpoch != nil { - xint644 = *(*source).LastUpdateTimeSinceEpoch - } - dbArtifact.LastUpdateTimeSinceEpoch = xint644 - dbArtifactPropertyList, err := converter.ConvertProtoArtifactProperties(source) - if err != nil { - return nil, fmt.Errorf("error setting field Properties: %w", err) - } - dbArtifact.Properties = dbArtifactPropertyList - pDbArtifact = &dbArtifact - } - return pDbArtifact, nil -} -func (c *GRPCConverterImpl) ConvertAssociation(source *proto.Association) (*db.Association, error) { - var pDbAssociation *db.Association - if source != nil { - var dbAssociation db.Association - var xint64 int64 - if (*source).ContextId != nil { - xint64 = *(*source).ContextId - } - dbAssociation.ContextID = xint64 - var xint642 int64 - if (*source).ExecutionId != nil { - xint642 = *(*source).ExecutionId - } - dbAssociation.ExecutionID = xint642 - pDbAssociation = &dbAssociation - } - return pDbAssociation, nil -} -func (c *GRPCConverterImpl) ConvertAttribution(source *proto.Attribution) (*db.Attribution, error) { - var pDbAttribution *db.Attribution - if source != nil { - var dbAttribution db.Attribution - var xint64 int64 - if (*source).ContextId != nil { - xint64 = *(*source).ContextId - } - dbAttribution.ContextID = xint64 - var xint642 int64 - if (*source).ArtifactId != nil { - xint642 = *(*source).ArtifactId - } - dbAttribution.ArtifactID = xint642 - pDbAttribution = &dbAttribution - } - return pDbAttribution, nil -} -func (c *GRPCConverterImpl) ConvertContext(source *proto.Context) (*db.Context, error) { - var pDbContext *db.Context - if source != nil { - var dbContext db.Context - var xint64 int64 - if (*source).Id != nil { - xint64 = *(*source).Id - } - dbContext.ID = xint64 - var xint642 int64 - if (*source).TypeId != nil { - xint642 = *(*source).TypeId - } - dbContext.TypeID = xint642 - var xstring string - if (*source).Name != nil { - xstring = *(*source).Name - } - dbContext.Name = xstring - var pString *string - if (*source).ExternalId != nil { - xstring2 := *(*source).ExternalId - pString = &xstring2 - } - dbContext.ExternalID = pString - var xint643 int64 - if (*source).CreateTimeSinceEpoch != nil { - xint643 = *(*source).CreateTimeSinceEpoch - } - dbContext.CreateTimeSinceEpoch = xint643 - var xint644 int64 - if (*source).LastUpdateTimeSinceEpoch != nil { - xint644 = *(*source).LastUpdateTimeSinceEpoch - } - dbContext.LastUpdateTimeSinceEpoch = xint644 - dbContextPropertyList, err := converter.ConvertProtoContextProperties(source) - if err != nil { - return nil, fmt.Errorf("error setting field Properties: %w", err) - } - dbContext.Properties = dbContextPropertyList - pDbContext = &dbContext - } - return pDbContext, nil -} -func (c *GRPCConverterImpl) ConvertEvent(source *proto.Event) (*db.Event, error) { - var pDbEvent *db.Event - if source != nil { - var dbEvent db.Event - var xint64 int64 - if (*source).ArtifactId != nil { - xint64 = *(*source).ArtifactId - } - dbEvent.ArtifactID = xint64 - var xint642 int64 - if (*source).ExecutionId != nil { - xint642 = *(*source).ExecutionId - } - dbEvent.ExecutionID = xint642 - dbEvent.Type = converter.ConvertProtoEventType((*source).Type) - var xint643 int64 - if (*source).MillisecondsSinceEpoch != nil { - xint643 = *(*source).MillisecondsSinceEpoch - } - dbEvent.MillisecondsSinceEpoch = xint643 - dbEventPathList, err := converter.ConvertProtoEventPath((*source).Path) - if err != nil { - return nil, fmt.Errorf("error setting field PathSteps: %w", err) - } - dbEvent.PathSteps = dbEventPathList - pDbEvent = &dbEvent - } - return pDbEvent, nil -} -func (c *GRPCConverterImpl) ConvertExecution(source *proto.Execution) (*db.Execution, error) { - var pDbExecution *db.Execution - if source != nil { - var dbExecution db.Execution - var xint64 int64 - if (*source).Id != nil { - xint64 = *(*source).Id - } - dbExecution.ID = xint64 - var xint642 int64 - if (*source).TypeId != nil { - xint642 = *(*source).TypeId - } - dbExecution.TypeID = xint642 - dbExecution.LastKnownState = converter.ConvertExecution_State((*source).LastKnownState) - var pString *string - if (*source).Name != nil { - xstring := *(*source).Name - pString = &xstring - } - dbExecution.Name = pString - var pString2 *string - if (*source).ExternalId != nil { - xstring2 := *(*source).ExternalId - pString2 = &xstring2 - } - dbExecution.ExternalID = pString2 - var xint643 int64 - if (*source).CreateTimeSinceEpoch != nil { - xint643 = *(*source).CreateTimeSinceEpoch - } - dbExecution.CreateTimeSinceEpoch = xint643 - var xint644 int64 - if (*source).LastUpdateTimeSinceEpoch != nil { - xint644 = *(*source).LastUpdateTimeSinceEpoch - } - dbExecution.LastUpdateTimeSinceEpoch = xint644 - dbExecutionPropertyList, err := converter.ConvertProtoExecutionProperties(source) - if err != nil { - return nil, fmt.Errorf("error setting field Properties: %w", err) - } - dbExecution.Properties = dbExecutionPropertyList - pDbExecution = &dbExecution - } - return pDbExecution, nil -} -func (c *GRPCConverterImpl) ConvertToArtifact(source *db.Artifact) (*proto.Artifact, error) { - var pProtoArtifact *proto.Artifact - if source != nil { - var protoArtifact proto.Artifact - pInt64 := (*source).ID - protoArtifact.Id = &pInt64 - var pString *string - if (*source).Name != nil { - xstring := *(*source).Name - pString = &xstring - } - protoArtifact.Name = pString - pInt642 := (*source).TypeID - protoArtifact.TypeId = &pInt642 - pString2, err := converter.ConvertTypeIDToName((*source).ID) - if err != nil { - return nil, fmt.Errorf("error setting field Type: %w", err) - } - protoArtifact.Type = pString2 - var pString3 *string - if (*source).URI != nil { - xstring2 := *(*source).URI - pString3 = &xstring2 - } - protoArtifact.Uri = pString3 - var pString4 *string - if (*source).ExternalID != nil { - xstring3 := *(*source).ExternalID - pString4 = &xstring3 - } - protoArtifact.ExternalId = pString4 - mapStringPProtoValue, err := converter.ConvertToProtoArtifactProperties((*source).Properties) - if err != nil { - return nil, fmt.Errorf("error setting field Properties: %w", err) - } - protoArtifact.Properties = mapStringPProtoValue - mapStringPProtoValue2, err := converter.ConvertToProtoArtifactCustomProperties((*source).Properties) - if err != nil { - return nil, fmt.Errorf("error setting field CustomProperties: %w", err) - } - protoArtifact.CustomProperties = mapStringPProtoValue2 - pProtoArtifact_State, err := converter.ConvertToArtifact_State((*source).State) - if err != nil { - return nil, fmt.Errorf("error setting field State: %w", err) - } - protoArtifact.State = pProtoArtifact_State - pInt643 := (*source).CreateTimeSinceEpoch - protoArtifact.CreateTimeSinceEpoch = &pInt643 - pInt644 := (*source).LastUpdateTimeSinceEpoch - protoArtifact.LastUpdateTimeSinceEpoch = &pInt644 - pProtoArtifact = &protoArtifact - } - return pProtoArtifact, nil -} -func (c *GRPCConverterImpl) ConvertToAssociation(source *db.Association) (*proto.Association, error) { - var pProtoAssociation *proto.Association - if source != nil { - var protoAssociation proto.Association - pInt64 := (*source).ExecutionID - protoAssociation.ExecutionId = &pInt64 - pInt642 := (*source).ContextID - protoAssociation.ContextId = &pInt642 - pProtoAssociation = &protoAssociation - } - return pProtoAssociation, nil -} -func (c *GRPCConverterImpl) ConvertToAttribution(source *db.Attribution) (*proto.Attribution, error) { - var pProtoAttribution *proto.Attribution - if source != nil { - var protoAttribution proto.Attribution - pInt64 := (*source).ArtifactID - protoAttribution.ArtifactId = &pInt64 - pInt642 := (*source).ContextID - protoAttribution.ContextId = &pInt642 - pProtoAttribution = &protoAttribution - } - return pProtoAttribution, nil -} -func (c *GRPCConverterImpl) ConvertToContext(source *db.Context) (*proto.Context, error) { - var pProtoContext *proto.Context - if source != nil { - var protoContext proto.Context - pInt64 := (*source).ID - protoContext.Id = &pInt64 - pString := (*source).Name - protoContext.Name = &pString - pInt642 := (*source).TypeID - protoContext.TypeId = &pInt642 - pString2, err := converter.ConvertTypeIDToName((*source).ID) - if err != nil { - return nil, fmt.Errorf("error setting field Type: %w", err) - } - protoContext.Type = pString2 - var pString3 *string - if (*source).ExternalID != nil { - xstring := *(*source).ExternalID - pString3 = &xstring - } - protoContext.ExternalId = pString3 - mapStringPProtoValue, err := converter.ConvertToProtoContextProperties((*source).Properties) - if err != nil { - return nil, fmt.Errorf("error setting field Properties: %w", err) - } - protoContext.Properties = mapStringPProtoValue - mapStringPProtoValue2, err := converter.ConvertToProtoContextCustomProperties((*source).Properties) - if err != nil { - return nil, fmt.Errorf("error setting field CustomProperties: %w", err) - } - protoContext.CustomProperties = mapStringPProtoValue2 - pInt643 := (*source).CreateTimeSinceEpoch - protoContext.CreateTimeSinceEpoch = &pInt643 - pInt644 := (*source).LastUpdateTimeSinceEpoch - protoContext.LastUpdateTimeSinceEpoch = &pInt644 - pProtoContext = &protoContext - } - return pProtoContext, nil -} -func (c *GRPCConverterImpl) ConvertToEvent(source *db.Event) (*proto.Event, error) { - var pProtoEvent *proto.Event - if source != nil { - var protoEvent proto.Event - pInt64 := (*source).ArtifactID - protoEvent.ArtifactId = &pInt64 - pInt642 := (*source).ExecutionID - protoEvent.ExecutionId = &pInt642 - pProtoEvent_Path, err := converter.ConvertToProtoEventPath((*source).PathSteps) - if err != nil { - return nil, fmt.Errorf("error setting field Path: %w", err) - } - protoEvent.Path = pProtoEvent_Path - pProtoEvent_Type, err := converter.ConvertToProtoEventType((*source).Type) - if err != nil { - return nil, fmt.Errorf("error setting field Type: %w", err) - } - protoEvent.Type = pProtoEvent_Type - pInt643 := (*source).MillisecondsSinceEpoch - protoEvent.MillisecondsSinceEpoch = &pInt643 - pProtoEvent = &protoEvent - } - return pProtoEvent, nil -} -func (c *GRPCConverterImpl) ConvertToExecution(source *db.Execution) (*proto.Execution, error) { - var pProtoExecution *proto.Execution - if source != nil { - var protoExecution proto.Execution - pInt64 := (*source).ID - protoExecution.Id = &pInt64 - var pString *string - if (*source).Name != nil { - xstring := *(*source).Name - pString = &xstring - } - protoExecution.Name = pString - pInt642 := (*source).TypeID - protoExecution.TypeId = &pInt642 - pString2, err := converter.ConvertTypeIDToName((*source).ID) - if err != nil { - return nil, fmt.Errorf("error setting field Type: %w", err) - } - protoExecution.Type = pString2 - var pString3 *string - if (*source).ExternalID != nil { - xstring2 := *(*source).ExternalID - pString3 = &xstring2 - } - protoExecution.ExternalId = pString3 - pProtoExecution_State, err := converter.ConvertToExecution_State((*source).LastKnownState) - if err != nil { - return nil, fmt.Errorf("error setting field LastKnownState: %w", err) - } - protoExecution.LastKnownState = pProtoExecution_State - mapStringPProtoValue, err := converter.ConvertToProtoExecutionProperties((*source).Properties) - if err != nil { - return nil, fmt.Errorf("error setting field Properties: %w", err) - } - protoExecution.Properties = mapStringPProtoValue - mapStringPProtoValue2, err := converter.ConvertToProtoExecutionCustomProperties((*source).Properties) - if err != nil { - return nil, fmt.Errorf("error setting field CustomProperties: %w", err) - } - protoExecution.CustomProperties = mapStringPProtoValue2 - pInt643 := (*source).CreateTimeSinceEpoch - protoExecution.CreateTimeSinceEpoch = &pInt643 - pInt644 := (*source).LastUpdateTimeSinceEpoch - protoExecution.LastUpdateTimeSinceEpoch = &pInt644 - pProtoExecution = &protoExecution - } - return pProtoExecution, nil -} diff --git a/internal/converter/grpc_converter.go b/internal/converter/grpc_converter.go deleted file mode 100644 index 29238e82..00000000 --- a/internal/converter/grpc_converter.go +++ /dev/null @@ -1,84 +0,0 @@ -package converter - -import ( - "fmt" - - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/db" - "gorm.io/gorm" -) - -var ( - // singleton DB connection for type name lookup - globalDB *gorm.DB -) - -// SetConverterDB must be called before using gRPC converters, -// it uses the singleton DB connection to lookup type names -func SetConverterDB(db *gorm.DB) error { - if globalDB != nil { - return fmt.Errorf("converter global DB connection MUST only be set once") - } - globalDB = db - return initTypeNameCache() -} - -// goverter:converter -// goverter:output:file ./generated/grpc_converter.gen.go -// goverter:wrapErrors -// goverter:matchIgnoreCase -// goverter:useZeroValueOnPointerInconsistency -type GRPCConverter interface { - // goverter:map State | ConvertArtifact_State - // goverter:map . Properties | ConvertProtoArtifactProperties - // goverter:ignore ArtifactType Attributions Events - ConvertArtifact(source *proto.Artifact) (*db.Artifact, error) - // goverter:map State | ConvertToArtifact_State - // goverter:map ID Id - // goverter:map ID Type | ConvertTypeIDToName - // goverter:map Properties Properties | ConvertToProtoArtifactProperties - // goverter:map Properties CustomProperties | ConvertToProtoArtifactCustomProperties - // goverter:ignore state sizeCache unknownFields SystemMetadata - ConvertToArtifact(source *db.Artifact) (*proto.Artifact, error) - - // goverter:map . Properties | ConvertProtoContextProperties - // goverter:ignore ContextType Attributions Associations Parents Children - ConvertContext(source *proto.Context) (*db.Context, error) - // goverter:map ID Id - // goverter:map ID Type | ConvertTypeIDToName - // goverter:map Properties | ConvertToProtoContextProperties - // goverter:map Properties CustomProperties | ConvertToProtoContextCustomProperties - // goverter:ignore state sizeCache unknownFields SystemMetadata - ConvertToContext(source *db.Context) (*proto.Context, error) - - // goverter:map LastKnownState | ConvertExecution_State - // goverter:map . Properties | ConvertProtoExecutionProperties - // goverter:ignore ExecutionType Associations Events - ConvertExecution(source *proto.Execution) (*db.Execution, error) - // goverter:map ID Id - // goverter:map ID Type | ConvertTypeIDToName - // goverter:map LastKnownState | ConvertToExecution_State - // goverter:map Properties | ConvertToProtoExecutionProperties - // goverter:map Properties CustomProperties | ConvertToProtoExecutionCustomProperties - // goverter:ignore state sizeCache unknownFields SystemMetadata - ConvertToExecution(source *db.Execution) (*proto.Execution, error) - - // goverter:map Type | ConvertProtoEventType - // goverter:map Path PathSteps | ConvertProtoEventPath - // goverter:ignore ID Artifact Execution - ConvertEvent(source *proto.Event) (*db.Event, error) - // goverter:map Type | ConvertToProtoEventType - // goverter:map PathSteps Path | ConvertToProtoEventPath - // goverter:ignore state sizeCache unknownFields SystemMetadata - ConvertToEvent(source *db.Event) (*proto.Event, error) - - // goverter:ignore ID Context Artifact - ConvertAttribution(source *proto.Attribution) (*db.Attribution, error) - // goverter:ignore ID state sizeCache unknownFields - ConvertToAttribution(source *db.Attribution) (*proto.Attribution, error) - - // goverter:ignore ID Context Execution - ConvertAssociation(source *proto.Association) (*db.Association, error) - // goverter:ignore state sizeCache unknownFields - ConvertToAssociation(source *db.Association) (*proto.Association, error) -} diff --git a/internal/converter/grpc_converter_util.go b/internal/converter/grpc_converter_util.go deleted file mode 100644 index d54425e1..00000000 --- a/internal/converter/grpc_converter_util.go +++ /dev/null @@ -1,371 +0,0 @@ -package converter - -import ( - "fmt" - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/db" - "google.golang.org/protobuf/types/known/anypb" - "google.golang.org/protobuf/types/known/structpb" - "sync" -) - -var typeNameCache = map[int64]string{} -var cacheMutex = sync.Mutex{} - -func initTypeNameCache() error { - cacheMutex.Lock() - defer cacheMutex.Unlock() - - var types []db.Type - if err := globalDB.Model(db.Type{}).Select("id", "name").Find(&types).Error; err != nil { - return fmt.Errorf("error initializing type id cache: %w", err) - } - for _, t := range types { - typeNameCache[t.ID] = t.Name - } - return nil -} - -func ConvertTypeIDToName(id int64) (*string, error) { - if id == 0 { - return nil, nil - } - - cacheMutex.Lock() - defer cacheMutex.Unlock() - - if name, ok := typeNameCache[id]; ok { - return &name, nil - } - if globalDB == nil { - return nil, fmt.Errorf("converter DB connection has not been initialized") - } - var name string - if err := globalDB.Model(db.Type{}).Select("name").Where("id = ?", id).First(&name).Error; err != nil { - return nil, fmt.Errorf("error getting type name for type id %d: %w", id, err) - } - - // update cache - typeNameCache[id] = name - - return &name, nil -} - -func ConvertToProtoArtifactProperties(source []db.ArtifactProperty) (map[string]*proto.Value, error) { - result := make(map[string]*proto.Value) - for _, prop := range source { - err := convertToProtoMetadataProperty(&prop, result, false) - if err != nil { - return nil, err - } - } - return result, nil -} - -func ConvertToProtoArtifactCustomProperties(source []db.ArtifactProperty) (map[string]*proto.Value, error) { - result := make(map[string]*proto.Value) - for _, prop := range source { - err := convertToProtoMetadataProperty(&prop, result, true) - if err != nil { - return nil, err - } - } - return result, nil -} - -func ConvertToProtoContextProperties(source []db.ContextProperty) (map[string]*proto.Value, error) { - result := make(map[string]*proto.Value) - for _, prop := range source { - err := convertToProtoMetadataProperty(&prop, result, false) - if err != nil { - return nil, err - } - } - return result, nil -} - -func ConvertToProtoContextCustomProperties(source []db.ContextProperty) (map[string]*proto.Value, error) { - result := make(map[string]*proto.Value) - for _, prop := range source { - err := convertToProtoMetadataProperty(&prop, result, true) - if err != nil { - return nil, err - } - } - return result, nil -} - -func ConvertToProtoExecutionProperties(source []db.ExecutionProperty) (map[string]*proto.Value, error) { - result := make(map[string]*proto.Value) - for _, prop := range source { - err := convertToProtoMetadataProperty(&prop, result, false) - if err != nil { - return nil, err - } - } - return result, nil -} - -func ConvertToProtoExecutionCustomProperties(source []db.ExecutionProperty) (map[string]*proto.Value, error) { - result := make(map[string]*proto.Value) - for _, prop := range source { - err := convertToProtoMetadataProperty(&prop, result, true) - if err != nil { - return nil, err - } - } - return result, nil -} - -func convertToProtoMetadataProperty(p db.MetadataProperty, result map[string]*proto.Value, customProperty bool) error { - if p.GetIsCustomProperty() == customProperty { - value, err := convertToProtoValue(p) - if err != nil { - return err - } - result[p.GetName()] = value - } - return nil -} - -func convertToProtoValue(prop db.MetadataProperty) (*proto.Value, error) { - result := proto.Value{} - if prop.GetIntValue() != nil { - result.Value = &proto.Value_IntValue{IntValue: *prop.GetIntValue()} - } - if prop.GetDoubleValue() != nil { - result.Value = &proto.Value_DoubleValue{DoubleValue: *prop.GetDoubleValue()} - } - if prop.GetStringValue() != nil { - result.Value = &proto.Value_StringValue{StringValue: *prop.GetStringValue()} - } - if prop.GetByteValue() != nil { - value := structpb.Struct{} - err := value.UnmarshalJSON(*prop.GetByteValue()) - if err != nil { - return nil, err - } - result.Value = &proto.Value_StructValue{StructValue: &value} - } - if prop.GetProtoValue() != nil { - value := anypb.Any{ - TypeUrl: *prop.GetTypeURL(), - Value: *prop.GetProtoValue(), - } - result.Value = &proto.Value_ProtoValue{ProtoValue: &value} - } - if prop.GetBoolValue() != nil { - result.Value = &proto.Value_BoolValue{BoolValue: *prop.GetBoolValue()} - } - return &result, nil -} - -func ConvertProtoArtifactProperties(source *proto.Artifact) ([]db.ArtifactProperty, error) { - var result []db.ArtifactProperty - var id int64 - if source.Id != nil { - id = *source.Id - } - err := convertArtifactProtoProperties(source.Properties, id, false, &result) - if err != nil { - return nil, err - } - err = convertArtifactProtoProperties(source.CustomProperties, id, true, &result) - if err != nil { - return nil, err - } - return result, nil -} - -func ConvertProtoContextProperties(source *proto.Context) ([]db.ContextProperty, error) { - var result []db.ContextProperty - var id int64 - if source.Id != nil { - id = *source.Id - } - err := convertContextProtoProperties(source.Properties, id, false, &result) - if err != nil { - return nil, err - } - err = convertContextProtoProperties(source.CustomProperties, id, true, &result) - if err != nil { - return nil, err - } - return result, nil -} - -func ConvertProtoExecutionProperties(source *proto.Execution) ([]db.ExecutionProperty, error) { - var result []db.ExecutionProperty - var id int64 - if source.Id != nil { - id = *source.Id - } - err := convertExecutionProtoProperties(source.Properties, id, false, &result) - if err != nil { - return nil, err - } - err = convertExecutionProtoProperties(source.CustomProperties, id, true, &result) - if err != nil { - return nil, err - } - return result, nil -} - -func convertArtifactProtoProperties(source map[string]*proto.Value, id int64, customProperty bool, result *[]db.ArtifactProperty) error { - for name, prop := range source { - if prop != nil { - ap := db.ArtifactProperty{Name: name, ArtifactID: id, IsCustomProperty: customProperty} - err := convertProtoValue(prop, &ap) - if err != nil { - return err - } - *result = append(*result, ap) - } - } - return nil -} - -func convertContextProtoProperties(source map[string]*proto.Value, id int64, customProperty bool, result *[]db.ContextProperty) error { - for name, prop := range source { - if prop != nil { - ap := db.ContextProperty{Name: name, ContextID: id, IsCustomProperty: customProperty} - err := convertProtoValue(prop, &ap) - if err != nil { - return err - } - *result = append(*result, ap) - } - } - return nil -} - -func convertExecutionProtoProperties(source map[string]*proto.Value, id int64, customProperty bool, result *[]db.ExecutionProperty) error { - for name, prop := range source { - if prop != nil { - ap := db.ExecutionProperty{Name: name, ExecutionID: id, IsCustomProperty: customProperty} - err := convertProtoValue(prop, &ap) - if err != nil { - return err - } - *result = append(*result, ap) - } - } - return nil -} - -func convertProtoValue(source *proto.Value, target db.MetadataProperty) error { - switch p := source.Value.(type) { - case *proto.Value_IntValue: - target.SetIntValue(&p.IntValue) - case *proto.Value_DoubleValue: - target.SetDoubleValue(&p.DoubleValue) - case *proto.Value_StringValue: - target.SetStringValue(&p.StringValue) - case *proto.Value_StructValue: - bytes, err := p.StructValue.MarshalJSON() - if err != nil { - return fmt.Errorf("error converting struct value: %w", err) - } - target.SetByteValue(&bytes) - case *proto.Value_ProtoValue: - target.SetTypeURL(&p.ProtoValue.TypeUrl) - target.SetProtoValue(&p.ProtoValue.Value) - case *proto.Value_BoolValue: - target.SetBoolValue(&p.BoolValue) - } - return nil -} - -func ConvertArtifact_State(source *proto.Artifact_State) *int8 { - if source == nil { - return nil - } - state := int8((*source).Number()) - return &state -} - -func ConvertToArtifact_State(source *int8) (*proto.Artifact_State, error) { - if source == nil { - return nil, nil - } - if _, ok := proto.Artifact_State_name[int32(*source)]; !ok { - return nil, fmt.Errorf("invalid artifact state %d", *source) - } - state := proto.Artifact_State(*source) - return &state, nil -} - -func ConvertExecution_State(source *proto.Execution_State) *int8 { - if source == nil { - return nil - } - state := int8((*source).Number()) - return &state -} - -func ConvertToExecution_State(source *int8) (*proto.Execution_State, error) { - if source == nil { - return nil, nil - } - if _, ok := proto.Execution_State_name[int32(*source)]; !ok { - return nil, fmt.Errorf("invalid execution state %d", *source) - } - state := proto.Execution_State(*source) - return &state, nil -} - -func ConvertProtoEventType(source *proto.Event_Type) int8 { - if source == nil { - return int8(proto.Event_UNKNOWN) - } - return int8((*source).Number()) -} - -func ConvertToProtoEventType(source int8) (*proto.Event_Type, error) { - if _, ok := proto.Event_Type_name[int32(source)]; !ok { - return nil, fmt.Errorf("invalid event type %d", source) - } - state := proto.Event_Type(source) - return &state, nil -} - -func ConvertProtoEventPath(source *proto.Event_Path) ([]db.EventPath, error) { - var result []db.EventPath - if source != nil { - for _, step := range source.Steps { - switch s := step.Value.(type) { - case *proto.Event_Path_Step_Index: - i := int(s.Index) - result = append(result, db.EventPath{ - IsIndexStep: true, - StepIndex: &i, - }) - case *proto.Event_Path_Step_Key: - result = append(result, db.EventPath{ - IsIndexStep: false, - StepKey: &s.Key, - }) - } - } - } - return result, nil -} - -func ConvertToProtoEventPath(source []db.EventPath) (*proto.Event_Path, error) { - if len(source) == 0 { - return nil, nil - } - var result proto.Event_Path - for _, step := range source { - if step.IsIndexStep { - result.Steps = append(result.Steps, &proto.Event_Path_Step{ - Value: &proto.Event_Path_Step_Index{Index: int64(*step.StepIndex)}, - }) - } else { - result.Steps = append(result.Steps, &proto.Event_Path_Step{ - Value: &proto.Event_Path_Step_Key{Key: *step.StepKey}, - }) - } - } - return &result, nil -} diff --git a/internal/converter/grpc_converter_util_test.go b/internal/converter/grpc_converter_util_test.go deleted file mode 100644 index b3e720b7..00000000 --- a/internal/converter/grpc_converter_util_test.go +++ /dev/null @@ -1,876 +0,0 @@ -package converter - -import ( - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/db" - "google.golang.org/protobuf/types/known/anypb" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "gorm.io/gorm/logger" - "log" - "os" - "reflect" - "testing" - "time" -) - -func TestConvertArtifact_State(t *testing.T) { - type args struct { - source *proto.Artifact_State - } - pending := proto.Artifact_PENDING - var pendingInt int8 = 1 - tests := []struct { - name string - args args - want *int8 - }{ - { - name: "valid state", - args: args{source: &pending}, - want: &pendingInt, - }, - { - name: "nil state", - args: args{source: nil}, - want: nil, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := ConvertArtifact_State(tt.args.source); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertArtifact_State() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToArtifact_State(t *testing.T) { - type args struct { - source *int8 - } - pendingState := int8(db.PENDING) - pendingProto := proto.Artifact_PENDING - invalidState := int8(-1) - tests := []struct { - name string - args args - want *proto.Artifact_State - wantErr bool - }{ - { - name: "valid state", - args: args{source: &pendingState}, - want: &pendingProto, - wantErr: false, - }, - { - name: "invalid state", - args: args{source: &invalidState}, - want: nil, - wantErr: true, - }, - { - name: "nil state", - args: args{source: nil}, - want: nil, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToArtifact_State(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToArtifact_State() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToArtifact_State() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertExecution_State(t *testing.T) { - type args struct { - source *proto.Execution_State - } - newState := proto.Execution_NEW - newResult := int8(db.NEW) - tests := []struct { - name string - args args - want *int8 - }{ - { - name: "valid state", - args: args{source: &newState}, - want: &newResult, - }, - { - name: "nil state", - args: args{source: nil}, - want: nil, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := ConvertExecution_State(tt.args.source); !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertExecution_State() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToExecution_State(t *testing.T) { - type args struct { - source *int8 - } - newState := int8(db.NEW) - newProtoState := proto.Execution_NEW - invalidState := int8(-1) - tests := []struct { - name string - args args - want *proto.Execution_State - wantErr bool - }{ - { - name: "valid state", - args: args{source: &newState}, - want: &newProtoState, - wantErr: false, - }, - { - name: "invalid state", - args: args{source: &invalidState}, - want: nil, - wantErr: true, - }, - { - name: "nil state", - args: args{source: nil}, - want: nil, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToExecution_State(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToExecution_State() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToExecution_State() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertProtoArtifactProperties(t *testing.T) { - type args struct { - source *proto.Artifact - } - testStr := "test" - intValue := int64(10) - boolValue := true - doubleValue := 98.6 - tests := []struct { - name string - args args - want []db.ArtifactProperty - wantErr bool - }{ - { - name: "nil artifact id", - args: args{source: &proto.Artifact{ - Id: nil, - Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, - CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, - }}, - want: []db.ArtifactProperty{ - {Name: "prop1", StringValue: &testStr}, - {Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, - }, - wantErr: false, - }, - { - name: "valid artifact id", - args: args{source: &proto.Artifact{ - Id: &intValue, - Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_DoubleValue{DoubleValue: doubleValue}}}, - CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_BoolValue{BoolValue: boolValue}}}, - }}, - want: []db.ArtifactProperty{ - {ArtifactID: intValue, Name: "prop1", DoubleValue: &doubleValue}, - {ArtifactID: intValue, Name: "prop2", IsCustomProperty: true, BoolValue: &boolValue}, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertProtoArtifactProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertProtoArtifactProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertProtoArtifactProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertProtoContextProperties(t *testing.T) { - type args struct { - source *proto.Context - } - testStr := "test" - intValue := int64(10) - tests := []struct { - name string - args args - want []db.ContextProperty - wantErr bool - }{ - { - name: "nil context id", - args: args{source: &proto.Context{ - Id: nil, - Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, - CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, - }}, - want: []db.ContextProperty{ - {Name: "prop1", StringValue: &testStr}, - {Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, - }, - wantErr: false, - }, - { - name: "valid context id", - args: args{source: &proto.Context{ - Id: &intValue, - Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, - CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, - }}, - want: []db.ContextProperty{ - {ContextID: intValue, Name: "prop1", StringValue: &testStr}, - {ContextID: intValue, Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertProtoContextProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertProtoContextProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertProtoContextProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertProtoEventPath(t *testing.T) { - type args struct { - source *proto.Event_Path - } - stepIndex := 1 - stepKey := "my-key" - tests := []struct { - name string - args args - want []db.EventPath - wantErr bool - }{ - { - name: "step index", - args: args{source: &proto.Event_Path{Steps: []*proto.Event_Path_Step{{Value: &proto.Event_Path_Step_Index{Index: int64(stepIndex)}}}}}, - want: []db.EventPath{{IsIndexStep: true, StepIndex: &stepIndex}}, - wantErr: false, - }, - { - name: "step key", - args: args{source: &proto.Event_Path{Steps: []*proto.Event_Path_Step{{Value: &proto.Event_Path_Step_Key{Key: stepKey}}}}}, - want: []db.EventPath{{StepKey: &stepKey}}, - wantErr: false, - }, - { - name: "nil path", - args: args{}, - want: nil, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertProtoEventPath(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertProtoEventPath() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertProtoEventPath() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertProtoEventType(t *testing.T) { - type args struct { - source *proto.Event_Type - } - validEventType := proto.Event_DECLARED_INPUT - tests := []struct { - name string - args args - want int8 - }{ - { - name: "valid proto event type", - args: args{source: &validEventType}, - want: 2, - }, - { - name: "nil proto event type", - args: args{}, - want: int8(db.EVENT_TYPE_UNKNOWN), - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := ConvertProtoEventType(tt.args.source); got != tt.want { - t.Errorf("ConvertProtoEventType() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertProtoExecutionProperties(t *testing.T) { - type args struct { - source *proto.Execution - } - testStr := "test" - intValue := int64(10) - tests := []struct { - name string - args args - want []db.ExecutionProperty - wantErr bool - }{ - { - name: "nil execution id", - args: args{source: &proto.Execution{ - Id: nil, - Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, - CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, - }}, - want: []db.ExecutionProperty{ - {Name: "prop1", StringValue: &testStr}, - {Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, - }, - wantErr: false, - }, - { - name: "valid execution id", - args: args{source: &proto.Execution{ - Id: &intValue, - Properties: map[string]*proto.Value{"prop1": {Value: &proto.Value_StringValue{StringValue: testStr}}}, - CustomProperties: map[string]*proto.Value{"prop2": {Value: &proto.Value_IntValue{IntValue: intValue}}}, - }}, - want: []db.ExecutionProperty{ - {ExecutionID: intValue, Name: "prop1", StringValue: &testStr}, - {ExecutionID: intValue, Name: "prop2", IsCustomProperty: true, IntValue: &intValue}, - }, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertProtoExecutionProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertProtoExecutionProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertProtoExecutionProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoArtifactCustomProperties(t *testing.T) { - type args struct { - source []db.ArtifactProperty - } - intValue := int64(1) - stringValue := "test" - bytes := []byte(stringValue) - tests := []struct { - name string - args args - want map[string]*proto.Value - wantErr bool - }{ - { - name: "valid custom properties", - args: args{source: []db.ArtifactProperty{ - {Name: "notCustomProp", IntValue: &intValue}, - {Name: "customProp", IsCustomProperty: true, StringValue: &stringValue}, - }}, - want: map[string]*proto.Value{"customProp": {Value: &proto.Value_StringValue{StringValue: stringValue}}}, - wantErr: false, - }, - { - name: "invalid bytes property", - args: args{source: []db.ArtifactProperty{ - {Name: "notCustomProp", IntValue: &intValue}, - {Name: "customProp", IsCustomProperty: true, ByteValue: &bytes}, - }}, - want: nil, - wantErr: true, - }, - { - name: "no properties", - want: map[string]*proto.Value{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoArtifactCustomProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoArtifactCustomProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoArtifactCustomProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoArtifactProperties(t *testing.T) { - type args struct { - source []db.ArtifactProperty - } - doubleValue := 98.6 - boolValue := true - bytes := []byte("test") - tests := []struct { - name string - args args - want map[string]*proto.Value - wantErr bool - }{ - { - name: "valid non-custom properties", - args: args{source: []db.ArtifactProperty{ - {Name: "notCustomProp", DoubleValue: &doubleValue}, - {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, - }}, - want: map[string]*proto.Value{"notCustomProp": {Value: &proto.Value_DoubleValue{DoubleValue: doubleValue}}}, - wantErr: false, - }, - { - name: "invalid bytes property", - args: args{source: []db.ArtifactProperty{ - {Name: "notCustomProp", ByteValue: &bytes}, - {Name: "customProp", IsCustomProperty: true, DoubleValue: &doubleValue}, - }}, - want: nil, - wantErr: true, - }, - { - name: "no properties", - want: map[string]*proto.Value{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoArtifactProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoArtifactProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoArtifactProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoContextCustomProperties(t *testing.T) { - type args struct { - source []db.ContextProperty - } - intValue := int64(1) - stringValue := "test" - bytes := []byte(stringValue) - boolValue := true - tests := []struct { - name string - args args - want map[string]*proto.Value - wantErr bool - }{ - { - name: "valid custom properties", - args: args{source: []db.ContextProperty{ - {Name: "notCustomProp", IntValue: &intValue}, - {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, - }}, - want: map[string]*proto.Value{"customProp": {Value: &proto.Value_BoolValue{BoolValue: boolValue}}}, - wantErr: false, - }, - { - name: "invalid bytes property", - args: args{source: []db.ContextProperty{ - {Name: "notCustomProp", IntValue: &intValue}, - {Name: "customProp", IsCustomProperty: true, ByteValue: &bytes}, - }}, - want: nil, - wantErr: true, - }, - { - name: "no properties", - want: map[string]*proto.Value{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoContextCustomProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoContextCustomProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoContextCustomProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoContextProperties(t *testing.T) { - type args struct { - source []db.ContextProperty - } - doubleValue := 98.6 - boolValue := true - bytes := []byte("test") - typeUrl := "url://test" - tests := []struct { - name string - args args - want map[string]*proto.Value - wantErr bool - }{ - { - name: "valid non-custom properties", - args: args{source: []db.ContextProperty{ - {Name: "notCustomProp", ProtoValue: &bytes, TypeURL: &typeUrl}, - {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, - }}, - want: map[string]*proto.Value{ - "notCustomProp": {Value: &proto.Value_ProtoValue{ProtoValue: &anypb.Any{TypeUrl: typeUrl, Value: bytes}}}, - }, - wantErr: false, - }, - { - name: "invalid bytes property", - args: args{source: []db.ContextProperty{ - {Name: "notCustomProp", ByteValue: &bytes}, - {Name: "customProp", IsCustomProperty: true, DoubleValue: &doubleValue}, - }}, - want: nil, - wantErr: true, - }, - { - name: "no properties", - want: map[string]*proto.Value{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoContextProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoContextProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoContextProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoEventPath(t *testing.T) { - type args struct { - source []db.EventPath - } - stepIndex := 1 - stepKey := "test" - tests := []struct { - name string - args args - want *proto.Event_Path - wantErr bool - }{ - { - name: "valid path index", - args: args{source: []db.EventPath{{IsIndexStep: true, StepIndex: &stepIndex}}}, - want: &proto.Event_Path{Steps: []*proto.Event_Path_Step{ - {Value: &proto.Event_Path_Step_Index{Index: int64(stepIndex)}}, - }}, - wantErr: false, - }, - { - name: "valid path key", - args: args{source: []db.EventPath{{StepKey: &stepKey}}}, - want: &proto.Event_Path{Steps: []*proto.Event_Path_Step{ - {Value: &proto.Event_Path_Step_Key{Key: stepKey}}, - }}, - wantErr: false, - }, - { - name: "nil path", - want: nil, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoEventPath(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoEventPath() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoEventPath() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoEventType(t *testing.T) { - type args struct { - source int8 - } - validEventType := proto.Event_DECLARED_INPUT - unknownEventType := proto.Event_UNKNOWN - tests := []struct { - name string - args args - want *proto.Event_Type - wantErr bool - }{ - { - name: "valid event type", - args: args{source: int8(db.DECLARED_INPUT)}, - want: &validEventType, - wantErr: false, - }, - { - name: "nil event type", - args: args{}, - want: &unknownEventType, - wantErr: false, - }, - { - name: "invalid event type", - args: args{source: int8(-1)}, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoEventType(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoEventType() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoEventType() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoExecutionCustomProperties(t *testing.T) { - type args struct { - source []db.ExecutionProperty - } - intValue := int64(1) - stringValue := "test" - bytes := []byte(stringValue) - boolValue := true - tests := []struct { - name string - args args - want map[string]*proto.Value - wantErr bool - }{ - { - name: "valid custom properties", - args: args{source: []db.ExecutionProperty{ - {Name: "notCustomProp", IntValue: &intValue}, - {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, - }}, - want: map[string]*proto.Value{"customProp": {Value: &proto.Value_BoolValue{BoolValue: boolValue}}}, - wantErr: false, - }, - { - name: "invalid bytes property", - args: args{source: []db.ExecutionProperty{ - {Name: "notCustomProp", IntValue: &intValue}, - {Name: "customProp", IsCustomProperty: true, ByteValue: &bytes}, - }}, - want: nil, - wantErr: true, - }, - { - name: "no properties", - want: map[string]*proto.Value{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoExecutionCustomProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoExecutionCustomProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoExecutionCustomProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertToProtoExecutionProperties(t *testing.T) { - type args struct { - source []db.ExecutionProperty - } - doubleValue := 98.6 - boolValue := true - bytes := []byte("test") - typeUrl := "url://test" - tests := []struct { - name string - args args - want map[string]*proto.Value - wantErr bool - }{ - { - name: "valid non-custom properties", - args: args{source: []db.ExecutionProperty{ - {Name: "notCustomProp", ProtoValue: &bytes, TypeURL: &typeUrl}, - {Name: "customProp", IsCustomProperty: true, BoolValue: &boolValue}, - }}, - want: map[string]*proto.Value{ - "notCustomProp": {Value: &proto.Value_ProtoValue{ProtoValue: &anypb.Any{TypeUrl: typeUrl, Value: bytes}}}, - }, - wantErr: false, - }, - { - name: "invalid bytes property", - args: args{source: []db.ExecutionProperty{ - {Name: "notCustomProp", ByteValue: &bytes}, - {Name: "customProp", IsCustomProperty: true, DoubleValue: &doubleValue}, - }}, - want: nil, - wantErr: true, - }, - { - name: "no properties", - want: map[string]*proto.Value{}, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertToProtoExecutionProperties(tt.args.source) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertToProtoExecutionProperties() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertToProtoExecutionProperties() got = %v, want %v", got, tt.want) - } - }) - } -} - -func TestConvertTypeIDToName(t *testing.T) { - // setup mock DB - logger := logger.New( - log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer - logger.Config{ - SlowThreshold: time.Second, // Slow SQL threshold - LogLevel: logger.Info, // Log level - Colorful: true, // Disable color - }, - ) - dbConn, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{Logger: logger}) - if err != nil { - t.Errorf("failed to create mock Gorm connection: %v", err) - } - _ = dbConn.Migrator().AutoMigrate(db.Type{}) - _ = dbConn.Exec("INSERT INTO Type VALUES(1,'mlmd.Dataset',NULL,1,NULL,NULL,NULL,NULL)").Error - _ = SetConverterDB(dbConn) - // add a new type after the converter cache is initialized - _ = dbConn.Exec("INSERT INTO Type VALUES(2,'mlmd.Model',NULL,1,NULL,NULL,NULL,NULL)").Error - - type args struct { - id int64 - } - dataSet := "mlmd.Dataset" - model := "mlmd.Model" - tests := []struct { - name string - args args - want *string - wantErr bool - }{ - { - name: dataSet, - args: args{id: 1}, - want: &dataSet, - wantErr: false, - }, - { - name: model, - args: args{id: 2}, - want: &model, - wantErr: false, - }, - { - name: "missing id", - args: args{id: 3}, - want: nil, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := ConvertTypeIDToName(tt.args.id) - if (err != nil) != tt.wantErr { - t.Errorf("ConvertTypeIDToName() error = %v, wantErr %v", err, tt.wantErr) - return - } - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("ConvertTypeIDToName() got = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/internal/model/db/artifact.go b/internal/model/db/artifact.go deleted file mode 100644 index 7efefd58..00000000 --- a/internal/model/db/artifact.go +++ /dev/null @@ -1,52 +0,0 @@ -package db - -const TableNameArtifact = "Artifact" - -// Artifact mapped from table -type Artifact struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueArtifactTypeName,priority:1" json:"-"` - URI *string `gorm:"column:uri;type:text;index:idx_artifact_uri,priority:1" json:"-"` - State *int8 `gorm:"column:state" json:"-"` - Name *string `gorm:"column:name;type:varchar(255);uniqueIndex:UniqueArtifactTypeName,priority:2" json:"-"` - ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_artifact_external_id,priority:1" json:"-"` - CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_artifact_create_time_since_epoch,priority:1" json:"-"` - LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_artifact_last_update_time_since_epoch,priority:1" json:"-"` - - // relationships - Properties []ArtifactProperty - ArtifactType Type `gorm:"foreignKey:TypeID;references:ID"` - Attributions []Attribution `gorm:"foreignKey:ArtifactID;references:ID"` - Events []Event -} - -// TableName Artifact's table name -func (*Artifact) TableName() string { - return TableNameArtifact -} - -type ArtifactState int - -const ( - UNKNOWN ArtifactState = iota - // PENDING A state indicating that the artifact may exist. - PENDING - // LIVE A state indicating that the artifact should exist, unless something - // external to the system deletes it. - LIVE - // MARKED_FOR_DELETION A state indicating that the artifact should be deleted. - MARKED_FOR_DELETION - // DELETED A state indicating that the artifact has been deleted. - DELETED - // ABANDONED A state indicating that the artifact has been abandoned, which may be - // due to a failed or cancelled execution. - ABANDONED - // REFERENCE A state indicating that the artifact is a reference artifact. At - // execution start time, the orchestrator produces an output artifact for - // each output key with state PENDING. However, for an intermediate - // artifact, this first artifact's state will be REFERENCE. Intermediate - // artifacts emitted during a component's execution will copy the REFERENCE - // artifact's attributes. At the end of an execution, the artifact state - // should remain REFERENCE instead of being changed to LIVE. - REFERENCE -) diff --git a/internal/model/db/artifactproperty.go b/internal/model/db/artifactproperty.go deleted file mode 100644 index 2a8aa1e8..00000000 --- a/internal/model/db/artifactproperty.go +++ /dev/null @@ -1,102 +0,0 @@ -package db - -const TableNameArtifactProperty = "ArtifactProperty" - -// ArtifactProperty mapped from table -type ArtifactProperty struct { - ArtifactID int64 `gorm:"column:artifact_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey;index:idx_artifact_property_double,priority:1;index:idx_artifact_property_string,priority:1;index:idx_artifact_property_int,priority:1" json:"-"` - IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_artifact_property_double,priority:2;index:idx_artifact_property_string,priority:2;index:idx_artifact_property_int,priority:2" json:"-"` - IntValue *int64 `gorm:"column:int_value;index:idx_artifact_property_int,priority:3" json:"-"` - DoubleValue *float64 `gorm:"column:double_value;index:idx_artifact_property_double,priority:3" json:"-"` - StringValue *string `gorm:"column:string_value;index:idx_artifact_property_string,priority:3" json:"-"` - ByteValue *[]byte `gorm:"column:byte_value" json:"-"` - ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` - BoolValue *bool `gorm:"column:bool_value" json:"-"` - TypeURL *string `gorm:"column:type_url" json:"-"` -} - -// TableName ArtifactProperty's table name -func (*ArtifactProperty) TableName() string { - return TableNameArtifactProperty -} - -func (p *ArtifactProperty) GetID() int64 { - return p.ArtifactID -} - -func (p *ArtifactProperty) SetID(i int64) { - p.ArtifactID = i -} - -func (p *ArtifactProperty) GetName() string { - return p.Name -} - -func (p *ArtifactProperty) SetName(s string) { - p.Name = s -} - -func (p *ArtifactProperty) GetIsCustomProperty() bool { - return p.IsCustomProperty -} - -func (p *ArtifactProperty) SetIsCustomProperty(b bool) { - p.IsCustomProperty = b -} - -func (p *ArtifactProperty) GetIntValue() *int64 { - return p.IntValue -} - -func (p *ArtifactProperty) SetIntValue(i *int64) { - p.IntValue = i -} - -func (p *ArtifactProperty) GetDoubleValue() *float64 { - return p.DoubleValue -} - -func (p *ArtifactProperty) SetDoubleValue(f *float64) { - p.DoubleValue = f -} - -func (p *ArtifactProperty) GetStringValue() *string { - return p.StringValue -} - -func (p *ArtifactProperty) SetStringValue(s *string) { - p.StringValue = s -} - -func (p *ArtifactProperty) GetByteValue() *[]byte { - return p.ByteValue -} - -func (p *ArtifactProperty) SetByteValue(b *[]byte) { - p.ByteValue = b -} - -func (p *ArtifactProperty) GetProtoValue() *[]byte { - return p.ProtoValue -} - -func (p *ArtifactProperty) SetProtoValue(b *[]byte) { - p.ProtoValue = b -} - -func (p *ArtifactProperty) GetBoolValue() *bool { - return p.BoolValue -} - -func (p *ArtifactProperty) SetBoolValue(b *bool) { - p.BoolValue = b -} - -func (p *ArtifactProperty) GetTypeURL() *string { - return p.TypeURL -} - -func (p *ArtifactProperty) SetTypeURL(s *string) { - p.TypeURL = s -} diff --git a/internal/model/db/association.go b/internal/model/db/association.go deleted file mode 100644 index 662fcd8f..00000000 --- a/internal/model/db/association.go +++ /dev/null @@ -1,17 +0,0 @@ -package db - -const TableNameAssociation = "Association" - -// Association mapped from table -type Association struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - ContextID int64 `gorm:"column:context_id;not null;uniqueIndex:UniqueAssociation,priority:1" json:"-"` - ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueAssociation,priority:2" json:"-"` - Context Context - Execution Execution -} - -// TableName Association's table name -func (*Association) TableName() string { - return TableNameAssociation -} diff --git a/internal/model/db/attribution.go b/internal/model/db/attribution.go deleted file mode 100644 index 3de48eff..00000000 --- a/internal/model/db/attribution.go +++ /dev/null @@ -1,17 +0,0 @@ -package db - -const TableNameAttribution = "Attribution" - -// Attribution mapped from table -type Attribution struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - ContextID int64 `gorm:"column:context_id;not null;uniqueIndex:UniqueAttribution,priority:1" json:"-"` - ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueAttribution,priority:2" json:"-"` - Context Context - Artifact Artifact -} - -// TableName Attribution's table name -func (*Attribution) TableName() string { - return TableNameAttribution -} diff --git a/internal/model/db/context.go b/internal/model/db/context.go deleted file mode 100644 index 991b6e4b..00000000 --- a/internal/model/db/context.go +++ /dev/null @@ -1,28 +0,0 @@ -package db - -const TableNameContext = "Context" - -// Context mapped from table -type Context struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueContextName,priority:1" json:"-"` - Name string `gorm:"column:name;not null;uniqueIndex:UniqueContextName,priority:2" json:"-"` - ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_context_external_id,priority:1" json:"-"` - CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_context_create_time_since_epoch,priority:1" json:"-"` - LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_context_last_update_time_since_epoch,priority:1" json:"-"` - - // relationships - Properties []ContextProperty - ContextType Type `gorm:"foreignKey:TypeID;references:ID"` - Attributions []Attribution `gorm:"foreignKey:ContextID;references:ID"` - Associations []Association `gorm:"foreignKey:ContextID;references:ID"` - - // many to many self-reference for context graphs - Parents []ParentContext `gorm:"foreignKey:ContextID;references:ID"` - Children []ParentContext `gorm:"foreignKey:ParentContextID;references:ID"` -} - -// TableName Context's table name -func (*Context) TableName() string { - return TableNameContext -} diff --git a/internal/model/db/contextproperty.go b/internal/model/db/contextproperty.go deleted file mode 100644 index 0c6b1609..00000000 --- a/internal/model/db/contextproperty.go +++ /dev/null @@ -1,102 +0,0 @@ -package db - -const TableNameContextProperty = "ContextProperty" - -// ContextProperty mapped from table -type ContextProperty struct { - ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey;index:idx_context_property_int,priority:1;index:idx_context_property_string,priority:1;index:idx_context_property_double,priority:1" json:"-"` - IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_context_property_int,priority:2;index:idx_context_property_string,priority:2;index:idx_context_property_double,priority:2" json:"-"` - IntValue *int64 `gorm:"column:int_value;index:idx_context_property_int,priority:3" json:"-"` - DoubleValue *float64 `gorm:"column:double_value;index:idx_context_property_double,priority:3" json:"-"` - StringValue *string `gorm:"column:string_value;index:idx_context_property_string,priority:3" json:"-"` - ByteValue *[]byte `gorm:"column:byte_value" json:"-"` - ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` - BoolValue *bool `gorm:"column:bool_value" json:"-"` - TypeURL *string `gorm:"column:type_url" json:"-"` -} - -// TableName ContextProperty's table name -func (*ContextProperty) TableName() string { - return TableNameContextProperty -} - -func (p *ContextProperty) GetID() int64 { - return p.ContextID -} - -func (p *ContextProperty) SetID(i int64) { - p.ContextID = i -} - -func (p *ContextProperty) GetName() string { - return p.Name -} - -func (p *ContextProperty) SetName(s string) { - p.Name = s -} - -func (p *ContextProperty) GetIsCustomProperty() bool { - return p.IsCustomProperty -} - -func (p *ContextProperty) SetIsCustomProperty(b bool) { - p.IsCustomProperty = b -} - -func (p *ContextProperty) GetIntValue() *int64 { - return p.IntValue -} - -func (p *ContextProperty) SetIntValue(i *int64) { - p.IntValue = i -} - -func (p *ContextProperty) GetDoubleValue() *float64 { - return p.DoubleValue -} - -func (p *ContextProperty) SetDoubleValue(f *float64) { - p.DoubleValue = f -} - -func (p *ContextProperty) GetStringValue() *string { - return p.StringValue -} - -func (p *ContextProperty) SetStringValue(s *string) { - p.StringValue = s -} - -func (p *ContextProperty) GetByteValue() *[]byte { - return p.ByteValue -} - -func (p *ContextProperty) SetByteValue(b *[]byte) { - p.ByteValue = b -} - -func (p *ContextProperty) GetProtoValue() *[]byte { - return p.ProtoValue -} - -func (p *ContextProperty) SetProtoValue(b *[]byte) { - p.ProtoValue = b -} - -func (p *ContextProperty) GetBoolValue() *bool { - return p.BoolValue -} - -func (p *ContextProperty) SetBoolValue(b *bool) { - p.BoolValue = b -} - -func (p *ContextProperty) GetTypeURL() *string { - return p.TypeURL -} - -func (p *ContextProperty) SetTypeURL(s *string) { - p.TypeURL = s -} diff --git a/internal/model/db/event.go b/internal/model/db/event.go deleted file mode 100644 index 414607dd..00000000 --- a/internal/model/db/event.go +++ /dev/null @@ -1,39 +0,0 @@ -package db - -const TableNameEvent = "Event" - -// Event mapped from table -type Event struct { - ID int64 `gorm:"column:id;not null;primaryKey;autoIncrement:true" json:"-"` - ArtifactID int64 `gorm:"column:artifact_id;not null;uniqueIndex:UniqueEvent,priority:1" json:"-"` - ExecutionID int64 `gorm:"column:execution_id;not null;uniqueIndex:UniqueEvent,priority:2;index:idx_event_execution_id,priority:1" json:"-"` - Type int8 `gorm:"column:type;not null;uniqueIndex:UniqueEvent,priority:3" json:"-"` - MillisecondsSinceEpoch int64 `gorm:"autoCreateTime:milli;column:milliseconds_since_epoch;not null" json:"-"` - - // relationships - PathSteps []EventPath - Artifact Artifact - Execution Execution -} - -// TableName Event's table name -func (*Event) TableName() string { - return TableNameEvent -} - -type EventType int - -// Events distinguish between an artifact that is written by the execution -// (possibly as a cache), versus artifacts that are part of the declared -// output of the Execution. For more information on what DECLARED_ means, -// see the comment on the message. -const ( - EVENT_TYPE_UNKNOWN EventType = iota - DECLARED_OUTPUT - DECLARED_INPUT - INPUT - OUTPUT - INTERNAL_INPUT - INTERNAL_OUTPUT - PENDING_OUTPUT -) diff --git a/internal/model/db/eventpath.go b/internal/model/db/eventpath.go deleted file mode 100644 index 600b1002..00000000 --- a/internal/model/db/eventpath.go +++ /dev/null @@ -1,16 +0,0 @@ -package db - -const TableNameEventPath = "EventPath" - -// EventPath mapped from table -type EventPath struct { - EventID int64 `gorm:"column:event_id;not null;index:idx_eventpath_event_id,priority:1" json:"-"` - IsIndexStep bool `gorm:"column:is_index_step;not null" json:"-"` - StepIndex *int `gorm:"column:step_index" json:"-"` - StepKey *string `gorm:"column:step_key" json:"-"` -} - -// TableName EventPath's table name -func (*EventPath) TableName() string { - return TableNameEventPath -} diff --git a/internal/model/db/execution.go b/internal/model/db/execution.go deleted file mode 100644 index fe067417..00000000 --- a/internal/model/db/execution.go +++ /dev/null @@ -1,37 +0,0 @@ -package db - -const TableNameExecution = "Execution" - -// Execution mapped from table -type Execution struct { - ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"-"` - TypeID int64 `gorm:"column:type_id;not null;uniqueIndex:UniqueExecutionTypeName,priority:1" json:"-"` - LastKnownState *int8 `gorm:"column:last_known_state" json:"-"` - Name *string `gorm:"column:name;type:varchar(255);uniqueIndex:UniqueExecutionTypeName,priority:2" json:"-"` - ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_execution_external_id,priority:1" json:"-"` - CreateTimeSinceEpoch int64 `gorm:"autoCreateTime:milli;column:create_time_since_epoch;not null;index:idx_execution_create_time_since_epoch,priority:1" json:"-"` - LastUpdateTimeSinceEpoch int64 `gorm:"autoUpdateTime:milli;column:last_update_time_since_epoch;not null;index:idx_execution_last_update_time_since_epoch,priority:1" json:"-"` - - // relationships - Properties []ExecutionProperty - ExecutionType Type `gorm:"foreignKey:TypeID;references:ID"` - Associations []Association `gorm:"foreignKey:ExecutionID;references:ID"` - Events []Event -} - -// TableName Execution's table name -func (*Execution) TableName() string { - return TableNameExecution -} - -type ExecutionState int - -const ( - EXECUTION_STATE_UNKNOWN ExecutionState = iota - NEW - RUNNING - COMPLETE - FAILED - CACHED - CANCELED -) diff --git a/internal/model/db/executionproperty.go b/internal/model/db/executionproperty.go deleted file mode 100644 index e40619a3..00000000 --- a/internal/model/db/executionproperty.go +++ /dev/null @@ -1,102 +0,0 @@ -package db - -const TableNameExecutionProperty = "ExecutionProperty" - -// ExecutionProperty mapped from table -type ExecutionProperty struct { - ExecutionID int64 `gorm:"column:execution_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey;index:idx_execution_property_string,priority:1;index:idx_execution_property_int,priority:1;index:idx_execution_property_double,priority:1" json:"-"` - IsCustomProperty bool `gorm:"column:is_custom_property;primaryKey;index:idx_execution_property_string,priority:2;index:idx_execution_property_int,priority:2;index:idx_execution_property_double,priority:2" json:"-"` - IntValue *int64 `gorm:"column:int_value;index:idx_execution_property_int,priority:3" json:"-"` - DoubleValue *float64 `gorm:"column:double_value;index:idx_execution_property_double,priority:3" json:"-"` - StringValue *string `gorm:"column:string_value;index:idx_execution_property_string,priority:3" json:"-"` - ByteValue *[]byte `gorm:"column:byte_value" json:"-"` - ProtoValue *[]byte `gorm:"column:proto_value" json:"-"` - BoolValue *bool `gorm:"column:bool_value" json:"-"` - TypeURL *string `gorm:"column:type_url" json:"-"` -} - -// TableName ExecutionProperty's table name -func (*ExecutionProperty) TableName() string { - return TableNameExecutionProperty -} - -func (p *ExecutionProperty) GetID() int64 { - return p.ExecutionID -} - -func (p *ExecutionProperty) SetID(i int64) { - p.ExecutionID = i -} - -func (p *ExecutionProperty) GetName() string { - return p.Name -} - -func (p *ExecutionProperty) SetName(s string) { - p.Name = s -} - -func (p *ExecutionProperty) GetIsCustomProperty() bool { - return p.IsCustomProperty -} - -func (p *ExecutionProperty) SetIsCustomProperty(b bool) { - p.IsCustomProperty = b -} - -func (p *ExecutionProperty) GetIntValue() *int64 { - return p.IntValue -} - -func (p *ExecutionProperty) SetIntValue(i *int64) { - p.IntValue = i -} - -func (p *ExecutionProperty) GetDoubleValue() *float64 { - return p.DoubleValue -} - -func (p *ExecutionProperty) SetDoubleValue(f *float64) { - p.DoubleValue = f -} - -func (p *ExecutionProperty) GetStringValue() *string { - return p.StringValue -} - -func (p *ExecutionProperty) SetStringValue(s *string) { - p.StringValue = s -} - -func (p *ExecutionProperty) GetByteValue() *[]byte { - return p.ByteValue -} - -func (p *ExecutionProperty) SetByteValue(b *[]byte) { - p.ByteValue = b -} - -func (p *ExecutionProperty) GetProtoValue() *[]byte { - return p.ProtoValue -} - -func (p *ExecutionProperty) SetProtoValue(b *[]byte) { - p.ProtoValue = b -} - -func (p *ExecutionProperty) GetBoolValue() *bool { - return p.BoolValue -} - -func (p *ExecutionProperty) SetBoolValue(b *bool) { - p.BoolValue = b -} - -func (p *ExecutionProperty) GetTypeURL() *string { - return p.TypeURL -} - -func (p *ExecutionProperty) SetTypeURL(s *string) { - p.TypeURL = s -} diff --git a/internal/model/db/mlmdenv.go b/internal/model/db/mlmdenv.go deleted file mode 100644 index e0b85cd3..00000000 --- a/internal/model/db/mlmdenv.go +++ /dev/null @@ -1,13 +0,0 @@ -package db - -const TableNameMLMDEnv = "MLMDEnv" - -// MLMDEnv mapped from table -type MLMDEnv struct { - SchemaVersion int64 `gorm:"column:schema_version;primaryKey" json:"-"` -} - -// TableName MLMDEnv's table name -func (*MLMDEnv) TableName() string { - return TableNameMLMDEnv -} diff --git a/internal/model/db/parentcontext.go b/internal/model/db/parentcontext.go deleted file mode 100644 index 5b0c4824..00000000 --- a/internal/model/db/parentcontext.go +++ /dev/null @@ -1,14 +0,0 @@ -package db - -const TableNameParentContext = "ParentContext" - -// ParentContext mapped from table -type ParentContext struct { - ContextID int64 `gorm:"column:context_id;primaryKey" json:"-"` - ParentContextID int64 `gorm:"column:parent_context_id;primaryKey;index:idx_parentcontext_parent_context_id,priority:1" json:"-"` -} - -// TableName ParentContext's table name -func (*ParentContext) TableName() string { - return TableNameParentContext -} diff --git a/internal/model/db/parenttype.go b/internal/model/db/parenttype.go deleted file mode 100644 index 5fc0b364..00000000 --- a/internal/model/db/parenttype.go +++ /dev/null @@ -1,14 +0,0 @@ -package db - -const TableNameParentType = "ParentType" - -// ParentType mapped from table -type ParentType struct { - TypeID int64 `gorm:"column:type_id;primaryKey" json:"-"` - ParentTypeID int64 `gorm:"column:parent_type_id;primaryKey" json:"-"` -} - -// TableName ParentType's table name -func (*ParentType) TableName() string { - return TableNameParentType -} diff --git a/internal/model/db/property_interface.go b/internal/model/db/property_interface.go deleted file mode 100644 index 18e512ac..00000000 --- a/internal/model/db/property_interface.go +++ /dev/null @@ -1,24 +0,0 @@ -package db - -type MetadataProperty interface { - GetID() int64 - SetID(int64) - GetName() string - SetName(string) - GetIsCustomProperty() bool - SetIsCustomProperty(bool) - GetIntValue() *int64 - SetIntValue(*int64) - GetDoubleValue() *float64 - SetDoubleValue(*float64) - GetStringValue() *string - SetStringValue(*string) - GetByteValue() *[]byte - SetByteValue(*[]byte) - GetProtoValue() *[]byte - SetProtoValue(*[]byte) - GetBoolValue() *bool - SetBoolValue(*bool) - GetTypeURL() *string - SetTypeURL(*string) -} diff --git a/internal/model/db/type.go b/internal/model/db/type.go deleted file mode 100644 index 4b30d57a..00000000 --- a/internal/model/db/type.go +++ /dev/null @@ -1,32 +0,0 @@ -package db - -const TableNameType = "Type" - -// Type mapped from table -type Type struct { - ID int64 `gorm:"column:id;not null;primaryKey;autoIncrement:true" json:"-"` - Name string `gorm:"column:name;type:varchar(255);not null;uniqueIndex:idx_type_name,priority:1" json:"-"` - Version *string `gorm:"column:version;type:varchar(255)" json:"-"` - TypeKind int8 `gorm:"column:type_kind;not null" json:"-"` - Description *string `gorm:"column:description;type:text" json:"-"` - InputType *string `gorm:"column:input_type;type:text" json:"-"` - OutputType *string `gorm:"column:output_type;type:text" json:"-"` - ExternalID *string `gorm:"column:external_id;type:varchar(255);uniqueIndex:idx_type_external_id,priority:1" json:"-"` - - // relationships - Properties []TypeProperty -} - -// TableName Type's table name -func (*Type) TableName() string { - return TableNameType -} - -type TypeKind int - -// artifact type values from ml-metadata table values -const ( - EXECUTION_TYPE TypeKind = iota - ARTIFACT_TYPE - CONTEXT_TYPE -) diff --git a/internal/model/db/typeproperty.go b/internal/model/db/typeproperty.go deleted file mode 100644 index 0e9c237c..00000000 --- a/internal/model/db/typeproperty.go +++ /dev/null @@ -1,15 +0,0 @@ -package db - -const TableNameTypeProperty = "TypeProperty" - -// TypeProperty mapped from table -type TypeProperty struct { - TypeID int64 `gorm:"column:type_id;primaryKey" json:"-"` - Name string `gorm:"column:name;primaryKey" json:"-"` - DataType int32 `gorm:"column:data_type;not null" json:"-"` -} - -// TableName TypeProperty's table name -func (*TypeProperty) TableName() string { - return TableNameTypeProperty -} diff --git a/internal/model/graph/models_gen.go b/internal/model/graph/models_gen.go deleted file mode 100644 index 91bcef90..00000000 --- a/internal/model/graph/models_gen.go +++ /dev/null @@ -1,562 +0,0 @@ -// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. - -package graph - -type ArtifactTypeInterface interface { - IsType() - IsArtifactTypeInterface() - GetID() *string - GetName() string - GetVersion() string - GetTypeKind() int - GetDescription() string - GetExternalID() *string - GetProperties() []*TypeProperty -} - -type ContextTypeInterface interface { - IsType() - IsContextTypeInterface() - GetID() *string - GetName() string - GetVersion() string - GetTypeKind() int - GetDescription() string - GetExternalID() *string - GetProperties() []*TypeProperty -} - -type ExecutionTypeInterface interface { - IsType() - IsExecutionTypeInterface() - GetID() *string - GetName() string - GetVersion() string - GetTypeKind() int - GetDescription() string - GetExternalID() *string - GetInputType() string - GetOutputType() string - GetProperties() []*TypeProperty -} - -type Type interface { - IsType() - GetID() *string - GetName() string - GetVersion() string - GetTypeKind() int - GetDescription() string - GetExternalID() *string - GetProperties() []*TypeProperty -} - -type Value interface { - IsValue() -} - -type Artifact struct { - ID *string `json:"id,omitempty"` - TypeID string `json:"typeId"` - URI string `json:"uri"` - State int `json:"state"` - Name string `json:"name"` - ExternalID *string `json:"externalId,omitempty"` - CreateTimeSinceEpoch int `json:"createTimeSinceEpoch"` - LastUpdateTimeSinceEpoch int `json:"lastUpdateTimeSinceEpoch"` - Type *ArtifactType `json:"type"` - Properties []*ArtifactProperty `json:"properties,omitempty"` -} - -type ArtifactProperty struct { - ArtifactID *string `json:"artifactId,omitempty"` - Name *string `json:"name,omitempty"` - IsCustomProperty bool `json:"isCustomProperty"` - PropertyValue Value `json:"propertyValue"` -} - -type ArtifactType struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (ArtifactType) IsArtifactTypeInterface() {} -func (this ArtifactType) GetID() *string { return this.ID } -func (this ArtifactType) GetName() string { return this.Name } -func (this ArtifactType) GetVersion() string { return this.Version } -func (this ArtifactType) GetTypeKind() int { return this.TypeKind } -func (this ArtifactType) GetDescription() string { return this.Description } -func (this ArtifactType) GetExternalID() *string { return this.ExternalID } -func (this ArtifactType) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (ArtifactType) IsType() {} - -type BoolValue struct { - Value bool `json:"value"` -} - -func (BoolValue) IsValue() {} - -type Context struct { - ID *string `json:"id,omitempty"` - TypeID string `json:"typeId"` - Name string `json:"name"` - ExternalID *string `json:"externalId,omitempty"` - CreateTimeSinceEpoch int `json:"createTimeSinceEpoch"` - LastUpdateTimeSinceEpoch int `json:"lastUpdateTimeSinceEpoch"` - Type *ContextType `json:"type"` - Parent *Context `json:"parent,omitempty"` - Children []*Context `json:"children,omitempty"` - Attributions []*Artifact `json:"attributions,omitempty"` - Associations []*Execution `json:"associations,omitempty"` - Properties []*ContextProperty `json:"properties,omitempty"` -} - -type ContextProperty struct { - ContextID *string `json:"contextId,omitempty"` - Name string `json:"name"` - IsCustomProperty int `json:"isCustomProperty"` - PropertyValue Value `json:"propertyValue"` -} - -type ContextType struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (ContextType) IsContextTypeInterface() {} -func (this ContextType) GetID() *string { return this.ID } -func (this ContextType) GetName() string { return this.Name } -func (this ContextType) GetVersion() string { return this.Version } -func (this ContextType) GetTypeKind() int { return this.TypeKind } -func (this ContextType) GetDescription() string { return this.Description } -func (this ContextType) GetExternalID() *string { return this.ExternalID } -func (this ContextType) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (ContextType) IsType() {} - -type DoubleValue struct { - Value float64 `json:"value"` -} - -func (DoubleValue) IsValue() {} - -type Event struct { - ID *string `json:"id,omitempty"` - ArtifactID string `json:"artifactId"` - ExecutionID string `json:"executionId"` - Type int `json:"type"` - Artifact *Artifact `json:"artifact,omitempty"` - Execution *Execution `json:"execution,omitempty"` - MillisecondsSinceEpoch int `json:"millisecondsSinceEpoch"` -} - -type EventPath struct { - EventID string `json:"eventId"` - IsIndexStep int `json:"isIndexStep"` - StepIndex int `json:"stepIndex"` - StepKey string `json:"stepKey"` -} - -type Execution struct { - ID *string `json:"id,omitempty"` - TypeID string `json:"typeId"` - LastKnownState int `json:"lastKnownState"` - Name string `json:"name"` - ExternalID *string `json:"externalId,omitempty"` - CreateTimeSinceEpoch int `json:"createTimeSinceEpoch"` - LastUpdateTimeSinceEpoch int `json:"lastUpdateTimeSinceEpoch"` - Type *ExecutionType `json:"type"` - Properties []*ExecutionProperty `json:"properties,omitempty"` -} - -type ExecutionProperty struct { - ExecutionID *string `json:"executionId,omitempty"` - Name string `json:"name"` - IsCustomProperty int `json:"isCustomProperty"` - PropertyValue Value `json:"propertyValue"` -} - -type ExecutionType struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - InputType string `json:"inputType"` - OutputType string `json:"outputType"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (ExecutionType) IsExecutionTypeInterface() {} -func (this ExecutionType) GetID() *string { return this.ID } -func (this ExecutionType) GetName() string { return this.Name } -func (this ExecutionType) GetVersion() string { return this.Version } -func (this ExecutionType) GetTypeKind() int { return this.TypeKind } -func (this ExecutionType) GetDescription() string { return this.Description } -func (this ExecutionType) GetExternalID() *string { return this.ExternalID } -func (this ExecutionType) GetInputType() string { return this.InputType } -func (this ExecutionType) GetOutputType() string { return this.OutputType } -func (this ExecutionType) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (ExecutionType) IsType() {} - -type InstanceFilter struct { - Ids []string `json:"ids,omitempty"` - TypeIds []string `json:"typeIds,omitempty"` - Names []string `json:"names,omitempty"` - ExternalIds []string `json:"externalIds,omitempty"` -} - -type IntValue struct { - Value int `json:"value"` -} - -func (IntValue) IsValue() {} - -type MlmdDataset struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdDataset) IsArtifactTypeInterface() {} -func (this MlmdDataset) GetID() *string { return this.ID } -func (this MlmdDataset) GetName() string { return this.Name } -func (this MlmdDataset) GetVersion() string { return this.Version } -func (this MlmdDataset) GetTypeKind() int { return this.TypeKind } -func (this MlmdDataset) GetDescription() string { return this.Description } -func (this MlmdDataset) GetExternalID() *string { return this.ExternalID } -func (this MlmdDataset) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdDataset) IsType() {} - -type MlmdDeploy struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - InputType string `json:"inputType"` - OutputType string `json:"outputType"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdDeploy) IsExecutionTypeInterface() {} -func (this MlmdDeploy) GetID() *string { return this.ID } -func (this MlmdDeploy) GetName() string { return this.Name } -func (this MlmdDeploy) GetVersion() string { return this.Version } -func (this MlmdDeploy) GetTypeKind() int { return this.TypeKind } -func (this MlmdDeploy) GetDescription() string { return this.Description } -func (this MlmdDeploy) GetExternalID() *string { return this.ExternalID } -func (this MlmdDeploy) GetInputType() string { return this.InputType } -func (this MlmdDeploy) GetOutputType() string { return this.OutputType } -func (this MlmdDeploy) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdDeploy) IsType() {} - -type MlmdEvaluate struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - InputType string `json:"inputType"` - OutputType string `json:"outputType"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdEvaluate) IsExecutionTypeInterface() {} -func (this MlmdEvaluate) GetID() *string { return this.ID } -func (this MlmdEvaluate) GetName() string { return this.Name } -func (this MlmdEvaluate) GetVersion() string { return this.Version } -func (this MlmdEvaluate) GetTypeKind() int { return this.TypeKind } -func (this MlmdEvaluate) GetDescription() string { return this.Description } -func (this MlmdEvaluate) GetExternalID() *string { return this.ExternalID } -func (this MlmdEvaluate) GetInputType() string { return this.InputType } -func (this MlmdEvaluate) GetOutputType() string { return this.OutputType } -func (this MlmdEvaluate) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdEvaluate) IsType() {} - -type MlmdMetrics struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdMetrics) IsArtifactTypeInterface() {} -func (this MlmdMetrics) GetID() *string { return this.ID } -func (this MlmdMetrics) GetName() string { return this.Name } -func (this MlmdMetrics) GetVersion() string { return this.Version } -func (this MlmdMetrics) GetTypeKind() int { return this.TypeKind } -func (this MlmdMetrics) GetDescription() string { return this.Description } -func (this MlmdMetrics) GetExternalID() *string { return this.ExternalID } -func (this MlmdMetrics) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdMetrics) IsType() {} - -type MlmdModel struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdModel) IsArtifactTypeInterface() {} -func (this MlmdModel) GetID() *string { return this.ID } -func (this MlmdModel) GetName() string { return this.Name } -func (this MlmdModel) GetVersion() string { return this.Version } -func (this MlmdModel) GetTypeKind() int { return this.TypeKind } -func (this MlmdModel) GetDescription() string { return this.Description } -func (this MlmdModel) GetExternalID() *string { return this.ExternalID } -func (this MlmdModel) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdModel) IsType() {} - -type MlmdProcess struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - InputType string `json:"inputType"` - OutputType string `json:"outputType"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdProcess) IsExecutionTypeInterface() {} -func (this MlmdProcess) GetID() *string { return this.ID } -func (this MlmdProcess) GetName() string { return this.Name } -func (this MlmdProcess) GetVersion() string { return this.Version } -func (this MlmdProcess) GetTypeKind() int { return this.TypeKind } -func (this MlmdProcess) GetDescription() string { return this.Description } -func (this MlmdProcess) GetExternalID() *string { return this.ExternalID } -func (this MlmdProcess) GetInputType() string { return this.InputType } -func (this MlmdProcess) GetOutputType() string { return this.OutputType } -func (this MlmdProcess) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdProcess) IsType() {} - -type MlmdStatistics struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdStatistics) IsArtifactTypeInterface() {} -func (this MlmdStatistics) GetID() *string { return this.ID } -func (this MlmdStatistics) GetName() string { return this.Name } -func (this MlmdStatistics) GetVersion() string { return this.Version } -func (this MlmdStatistics) GetTypeKind() int { return this.TypeKind } -func (this MlmdStatistics) GetDescription() string { return this.Description } -func (this MlmdStatistics) GetExternalID() *string { return this.ExternalID } -func (this MlmdStatistics) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdStatistics) IsType() {} - -type MlmdTrain struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - InputType string `json:"inputType"` - OutputType string `json:"outputType"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdTrain) IsExecutionTypeInterface() {} -func (this MlmdTrain) GetID() *string { return this.ID } -func (this MlmdTrain) GetName() string { return this.Name } -func (this MlmdTrain) GetVersion() string { return this.Version } -func (this MlmdTrain) GetTypeKind() int { return this.TypeKind } -func (this MlmdTrain) GetDescription() string { return this.Description } -func (this MlmdTrain) GetExternalID() *string { return this.ExternalID } -func (this MlmdTrain) GetInputType() string { return this.InputType } -func (this MlmdTrain) GetOutputType() string { return this.OutputType } -func (this MlmdTrain) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdTrain) IsType() {} - -type MlmdTransform struct { - ID *string `json:"id,omitempty"` - Name string `json:"name"` - Version string `json:"version"` - TypeKind int `json:"typeKind"` - Description string `json:"description"` - ExternalID *string `json:"externalId,omitempty"` - InputType string `json:"inputType"` - OutputType string `json:"outputType"` - Properties []*TypeProperty `json:"properties,omitempty"` -} - -func (MlmdTransform) IsExecutionTypeInterface() {} -func (this MlmdTransform) GetID() *string { return this.ID } -func (this MlmdTransform) GetName() string { return this.Name } -func (this MlmdTransform) GetVersion() string { return this.Version } -func (this MlmdTransform) GetTypeKind() int { return this.TypeKind } -func (this MlmdTransform) GetDescription() string { return this.Description } -func (this MlmdTransform) GetExternalID() *string { return this.ExternalID } -func (this MlmdTransform) GetInputType() string { return this.InputType } -func (this MlmdTransform) GetOutputType() string { return this.OutputType } -func (this MlmdTransform) GetProperties() []*TypeProperty { - if this.Properties == nil { - return nil - } - interfaceSlice := make([]*TypeProperty, 0, len(this.Properties)) - for _, concrete := range this.Properties { - interfaceSlice = append(interfaceSlice, concrete) - } - return interfaceSlice -} - -func (MlmdTransform) IsType() {} - -type StringValue struct { - Value string `json:"value"` -} - -func (StringValue) IsValue() {} - -type TypeFilter struct { - Ids []string `json:"ids,omitempty"` - Names []string `json:"names,omitempty"` - Versions []string `json:"versions,omitempty"` - ExternalIds []string `json:"externalIds,omitempty"` -} - -type TypeProperty struct { - TypeID string `json:"typeId"` - Name string `json:"name"` - DataType int `json:"dataType"` -} diff --git a/internal/model/library/metadata_library.go b/internal/model/library/metadata_library.go deleted file mode 100644 index 7ce2c84d..00000000 --- a/internal/model/library/metadata_library.go +++ /dev/null @@ -1,100 +0,0 @@ -package library - -import ( - "fmt" - "github.com/golang/glog" - "gopkg.in/yaml.v3" - "io/fs" - "os" - "path/filepath" - "strings" -) - -//go:generate go-enum -type=PropertyType - -type PropertyType int32 - -const ( - UNKNOWN PropertyType = iota - INT - DOUBLE - STRING - STRUCT - PROTO - BOOLEAN -) - -type MetadataType struct { - Name *string `yaml:"name,omitempty"` - Version *string `yaml:"version,omitempty"` - Description *string `yaml:"description,omitempty"` - ExternalId *string `yaml:"external_id,omitempty"` - Properties map[string]PropertyType `yaml:"properties,omitempty"` -} - -type ArtifactType struct { - MetadataType `yaml:",inline"` - // TODO add support for base type enum - //BaseType *ArtifactType_SystemDefinedBaseType `yaml:"base_type,omitempty"` -} - -type ContextType struct { - MetadataType `yaml:",inline"` -} - -type ExecutionType struct { - MetadataType `yaml:",inline"` - //InputType *ArtifactStructType `yaml:"input_type,omitempty"` - //OutputType *ArtifactStructType `yaml:"output_type,omitempty"` - //BaseType *ExecutionType_SystemDefinedBaseType `yaml:"base_type,omitempty"` -} - -type MetadataLibrary struct { - ArtifactTypes []ArtifactType `yaml:"artifact-types,omitempty"` - ContextTypes []ContextType `yaml:"context-types,omitempty"` - ExecutionTypes []ExecutionType `yaml:"execution-types,omitempty"` -} - -func LoadLibraries(dirs []string) (map[string]*MetadataLibrary, error) { - result := make(map[string]*MetadataLibrary) - for _, dir := range dirs { - abs, err := filepath.Abs(dir) - if err != nil { - return nil, fmt.Errorf("error getting absolute library path for %s: %w", dir, err) - } - _, err = os.Stat(abs) - if err != nil { - return nil, fmt.Errorf("error opening library path for %s: %w", abs, err) - } - err = filepath.WalkDir(abs, func(path string, entry fs.DirEntry, err error) error { - if err != nil { - glog.Warningf("error reading library path %s: %v", path, err) - return filepath.SkipDir - } - if entry.IsDir() || !isYamlFile(path) { - return nil - } - - bytes, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("failed to read library file %s: %w", path, err) - } - lib := &MetadataLibrary{} - err = yaml.Unmarshal(bytes, lib) - if err != nil { - return fmt.Errorf("failed to parse library file %s: %w", path, err) - } - result[path] = lib - return nil - }) - if err != nil { - return nil, fmt.Errorf("failed to read library directory %s: %w", abs, err) - } - } - return result, nil -} - -func isYamlFile(path string) bool { - lowerPath := strings.ToLower(filepath.Ext(path)) - return strings.HasSuffix(lowerPath, ".yaml") || strings.HasSuffix(lowerPath, ".yml") -} diff --git a/internal/model/library/propertytype_enum.go b/internal/model/library/propertytype_enum.go deleted file mode 100644 index 1c575b5e..00000000 --- a/internal/model/library/propertytype_enum.go +++ /dev/null @@ -1,271 +0,0 @@ -// Code generated by "go-enum -type=PropertyType"; DO NOT EDIT. - -// Install go-enum by `go get install github.com/searKing/golang/tools/go-enum` -package library - -import ( - "database/sql" - "database/sql/driver" - "encoding" - "encoding/json" - "fmt" - "strconv" -) - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[UNKNOWN-0] - _ = x[INT-1] - _ = x[DOUBLE-2] - _ = x[STRING-3] - _ = x[STRUCT-4] - _ = x[PROTO-5] - _ = x[BOOLEAN-6] -} - -const _PropertyType_name = "UNKNOWNINTDOUBLESTRINGSTRUCTPROTOBOOLEAN" - -var _PropertyType_index = [...]uint8{0, 7, 10, 16, 22, 28, 33, 40} - -func _() { - var _nil_PropertyType_value = func() (val PropertyType) { return }() - - // An "cannot convert PropertyType literal (type PropertyType) to type fmt.Stringer" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ fmt.Stringer = _nil_PropertyType_value -} - -func (i PropertyType) String() string { - if i < 0 || i >= PropertyType(len(_PropertyType_index)-1) { - return "PropertyType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _PropertyType_name[_PropertyType_index[i]:_PropertyType_index[i+1]] -} - -// New returns a pointer to a new addr filled with the PropertyType value passed in. -func (i PropertyType) New() *PropertyType { - clone := i - return &clone -} - -var _PropertyType_values = []PropertyType{0, 1, 2, 3, 4, 5, 6} - -var _PropertyType_name_to_values = map[string]PropertyType{ - _PropertyType_name[0:7]: 0, - _PropertyType_name[7:10]: 1, - _PropertyType_name[10:16]: 2, - _PropertyType_name[16:22]: 3, - _PropertyType_name[22:28]: 4, - _PropertyType_name[28:33]: 5, - _PropertyType_name[33:40]: 6, -} - -// ParsePropertyTypeString retrieves an enum value from the enum constants string name. -// Throws an error if the param is not part of the enum. -func ParsePropertyTypeString(s string) (PropertyType, error) { - if val, ok := _PropertyType_name_to_values[s]; ok { - return val, nil - } - return 0, fmt.Errorf("%s does not belong to PropertyType values", s) -} - -// PropertyTypeValues returns all values of the enum -func PropertyTypeValues() []PropertyType { - return _PropertyType_values -} - -// IsAPropertyType returns "true" if the value is listed in the enum definition. "false" otherwise -func (i PropertyType) Registered() bool { - for _, v := range _PropertyType_values { - if i == v { - return true - } - } - return false -} - -func _() { - var _nil_PropertyType_value = func() (val PropertyType) { return }() - - // An "cannot convert PropertyType literal (type PropertyType) to type encoding.BinaryMarshaler" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ encoding.BinaryMarshaler = &_nil_PropertyType_value - - // An "cannot convert PropertyType literal (type PropertyType) to type encoding.BinaryUnmarshaler" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ encoding.BinaryUnmarshaler = &_nil_PropertyType_value -} - -// MarshalBinary implements the encoding.BinaryMarshaler interface for PropertyType -func (i PropertyType) MarshalBinary() (data []byte, err error) { - return []byte(i.String()), nil -} - -// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface for PropertyType -func (i *PropertyType) UnmarshalBinary(data []byte) error { - var err error - *i, err = ParsePropertyTypeString(string(data)) - return err -} - -func _() { - var _nil_PropertyType_value = func() (val PropertyType) { return }() - - // An "cannot convert PropertyType literal (type PropertyType) to type json.Marshaler" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ json.Marshaler = _nil_PropertyType_value - - // An "cannot convert PropertyType literal (type PropertyType) to type encoding.Unmarshaler" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ json.Unmarshaler = &_nil_PropertyType_value -} - -// MarshalJSON implements the json.Marshaler interface for PropertyType -func (i PropertyType) MarshalJSON() ([]byte, error) { - return json.Marshal(i.String()) -} - -// UnmarshalJSON implements the json.Unmarshaler interface for PropertyType -func (i *PropertyType) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err != nil { - return fmt.Errorf("PropertyType should be a string, got %s", data) - } - - var err error - *i, err = ParsePropertyTypeString(s) - return err -} - -func _() { - var _nil_PropertyType_value = func() (val PropertyType) { return }() - - // An "cannot convert PropertyType literal (type PropertyType) to type encoding.TextMarshaler" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ encoding.TextMarshaler = _nil_PropertyType_value - - // An "cannot convert PropertyType literal (type PropertyType) to type encoding.TextUnmarshaler" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ encoding.TextUnmarshaler = &_nil_PropertyType_value -} - -// MarshalText implements the encoding.TextMarshaler interface for PropertyType -func (i PropertyType) MarshalText() ([]byte, error) { - return []byte(i.String()), nil -} - -// UnmarshalText implements the encoding.TextUnmarshaler interface for PropertyType -func (i *PropertyType) UnmarshalText(text []byte) error { - var err error - *i, err = ParsePropertyTypeString(string(text)) - return err -} - -//func _() { -// var _nil_PropertyType_value = func() (val PropertyType) { return }() -// -// // An "cannot convert PropertyType literal (type PropertyType) to type yaml.Marshaler" compiler error signifies that the base type have changed. -// // Re-run the go-enum command to generate them again. -// var _ yaml.Marshaler = _nil_PropertyType_value -// -// // An "cannot convert PropertyType literal (type PropertyType) to type yaml.Unmarshaler" compiler error signifies that the base type have changed. -// // Re-run the go-enum command to generate them again. -// var _ yaml.Unmarshaler = &_nil_PropertyType_value -//} - -// MarshalYAML implements a YAML Marshaler for PropertyType -func (i PropertyType) MarshalYAML() (interface{}, error) { - return i.String(), nil -} - -// UnmarshalYAML implements a YAML Unmarshaler for PropertyType -func (i *PropertyType) UnmarshalYAML(unmarshal func(interface{}) error) error { - var s string - if err := unmarshal(&s); err != nil { - return err - } - - var err error - *i, err = ParsePropertyTypeString(s) - return err -} - -func _() { - var _nil_PropertyType_value = func() (val PropertyType) { return }() - - // An "cannot convert PropertyType literal (type PropertyType) to type driver.Valuer" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ driver.Valuer = _nil_PropertyType_value - - // An "cannot convert PropertyType literal (type PropertyType) to type sql.Scanner" compiler error signifies that the base type have changed. - // Re-run the go-enum command to generate them again. - var _ sql.Scanner = &_nil_PropertyType_value -} - -func (i PropertyType) Value() (driver.Value, error) { - return i.String(), nil -} - -func (i *PropertyType) Scan(value interface{}) error { - if value == nil { - return nil - } - - str, ok := value.(string) - if !ok { - bytes, ok := value.([]byte) - if !ok { - return fmt.Errorf("value is not a byte slice") - } - - str = string(bytes[:]) - } - - val, err := ParsePropertyTypeString(str) - if err != nil { - return err - } - - *i = val - return nil -} - -// PropertyTypeSliceContains reports whether sunEnums is within enums. -func PropertyTypeSliceContains(enums []PropertyType, sunEnums ...PropertyType) bool { - var seenEnums = map[PropertyType]bool{} - for _, e := range sunEnums { - seenEnums[e] = false - } - - for _, v := range enums { - if _, has := seenEnums[v]; has { - seenEnums[v] = true - } - } - - for _, seen := range seenEnums { - if !seen { - return false - } - } - - return true -} - -// PropertyTypeSliceContainsAny reports whether any sunEnum is within enums. -func PropertyTypeSliceContainsAny(enums []PropertyType, sunEnums ...PropertyType) bool { - var seenEnums = map[PropertyType]struct{}{} - for _, e := range sunEnums { - seenEnums[e] = struct{}{} - } - - for _, v := range enums { - if _, has := seenEnums[v]; has { - return true - } - } - - return false -} diff --git a/internal/server/graph/base-schema.resolvers.go b/internal/server/graph/base-schema.resolvers.go deleted file mode 100644 index f4f61aa6..00000000 --- a/internal/server/graph/base-schema.resolvers.go +++ /dev/null @@ -1,22 +0,0 @@ -package graph - -// This file will be automatically regenerated based on the schema, any resolver implementations -// will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.36 - -import ( - "context" - - "github.com/opendatahub-io/model-registry/internal/model/graph" -) - -// Type is the resolver for the type field. -func (r *artifactResolver) Type(ctx context.Context, obj *graph.Artifact, filter *graph.InstanceFilter) (*graph.ArtifactType, error) { - id := "1" - return &graph.ArtifactType{ID: &id, Name: "TestType"}, nil -} - -// Artifact returns ArtifactResolver implementation. -func (r *Resolver) Artifact() ArtifactResolver { return &artifactResolver{r} } - -type artifactResolver struct{ *Resolver } diff --git a/internal/server/graph/generated.go b/internal/server/graph/generated.go deleted file mode 100644 index aae96e2b..00000000 --- a/internal/server/graph/generated.go +++ /dev/null @@ -1,15612 +0,0 @@ -// Code generated by github.com/99designs/gqlgen, DO NOT EDIT. - -package graph - -import ( - "bytes" - "context" - "errors" - "fmt" - "strconv" - "sync" - "sync/atomic" - - "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/introspection" - "github.com/opendatahub-io/model-registry/internal/model/graph" - gqlparser "github.com/vektah/gqlparser/v2" - "github.com/vektah/gqlparser/v2/ast" -) - -// region ************************** generated!.gotpl ************************** - -// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. -func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { - return &executableSchema{ - resolvers: cfg.Resolvers, - directives: cfg.Directives, - complexity: cfg.Complexity, - } -} - -type Config struct { - Resolvers ResolverRoot - Directives DirectiveRoot - Complexity ComplexityRoot -} - -type ResolverRoot interface { - Artifact() ArtifactResolver - Query() QueryResolver -} - -type DirectiveRoot struct { -} - -type ComplexityRoot struct { - Artifact struct { - CreateTimeSinceEpoch func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - LastUpdateTimeSinceEpoch func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - State func(childComplexity int) int - Type func(childComplexity int, filter *graph.InstanceFilter) int - TypeID func(childComplexity int) int - URI func(childComplexity int) int - } - - ArtifactProperty struct { - ArtifactID func(childComplexity int) int - IsCustomProperty func(childComplexity int) int - Name func(childComplexity int) int - PropertyValue func(childComplexity int) int - } - - ArtifactType struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - BoolValue struct { - Value func(childComplexity int) int - } - - Context struct { - Associations func(childComplexity int) int - Attributions func(childComplexity int) int - Children func(childComplexity int) int - CreateTimeSinceEpoch func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - LastUpdateTimeSinceEpoch func(childComplexity int) int - Name func(childComplexity int) int - Parent func(childComplexity int) int - Properties func(childComplexity int) int - Type func(childComplexity int) int - TypeID func(childComplexity int) int - } - - ContextProperty struct { - ContextID func(childComplexity int) int - IsCustomProperty func(childComplexity int) int - Name func(childComplexity int) int - PropertyValue func(childComplexity int) int - } - - ContextType struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - DoubleValue struct { - Value func(childComplexity int) int - } - - Event struct { - Artifact func(childComplexity int) int - ArtifactID func(childComplexity int) int - Execution func(childComplexity int) int - ExecutionID func(childComplexity int) int - ID func(childComplexity int) int - MillisecondsSinceEpoch func(childComplexity int) int - Type func(childComplexity int) int - } - - EventPath struct { - EventID func(childComplexity int) int - IsIndexStep func(childComplexity int) int - StepIndex func(childComplexity int) int - StepKey func(childComplexity int) int - } - - Execution struct { - CreateTimeSinceEpoch func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - LastKnownState func(childComplexity int) int - LastUpdateTimeSinceEpoch func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - Type func(childComplexity int) int - TypeID func(childComplexity int) int - } - - ExecutionProperty struct { - ExecutionID func(childComplexity int) int - IsCustomProperty func(childComplexity int) int - Name func(childComplexity int) int - PropertyValue func(childComplexity int) int - } - - ExecutionType struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - InputType func(childComplexity int) int - Name func(childComplexity int) int - OutputType func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - IntValue struct { - Value func(childComplexity int) int - } - - MlmdDataset struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdDeploy struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - InputType func(childComplexity int) int - Name func(childComplexity int) int - OutputType func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdEvaluate struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - InputType func(childComplexity int) int - Name func(childComplexity int) int - OutputType func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdMetrics struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdModel struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdProcess struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - InputType func(childComplexity int) int - Name func(childComplexity int) int - OutputType func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdStatistics struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - Name func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdTrain struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - InputType func(childComplexity int) int - Name func(childComplexity int) int - OutputType func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - MlmdTransform struct { - Description func(childComplexity int) int - ExternalID func(childComplexity int) int - ID func(childComplexity int) int - InputType func(childComplexity int) int - Name func(childComplexity int) int - OutputType func(childComplexity int) int - Properties func(childComplexity int) int - TypeKind func(childComplexity int) int - Version func(childComplexity int) int - } - - Query struct { - ArtifactTypes func(childComplexity int, filter *graph.TypeFilter) int - Artifacts func(childComplexity int, filter *graph.InstanceFilter) int - ContextTypes func(childComplexity int, filter *graph.TypeFilter) int - Contexts func(childComplexity int, filter *graph.InstanceFilter) int - Events func(childComplexity int) int - ExecutionTypes func(childComplexity int, filter *graph.TypeFilter) int - Executions func(childComplexity int, filter *graph.InstanceFilter) int - MlmdDataset func(childComplexity int, filter *graph.InstanceFilter) int - Types func(childComplexity int, filter *graph.TypeFilter) int - } - - StringValue struct { - Value func(childComplexity int) int - } - - TypeProperty struct { - DataType func(childComplexity int) int - Name func(childComplexity int) int - TypeID func(childComplexity int) int - } -} - -type ArtifactResolver interface { - Type(ctx context.Context, obj *graph.Artifact, filter *graph.InstanceFilter) (*graph.ArtifactType, error) -} -type QueryResolver interface { - Types(ctx context.Context, filter *graph.TypeFilter) ([]graph.Type, error) - ArtifactTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ArtifactType, error) - ContextTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ContextType, error) - ExecutionTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ExecutionType, error) - Artifacts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Artifact, error) - Contexts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Context, error) - Executions(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Execution, error) - Events(ctx context.Context) ([]*graph.Event, error) - MlmdDataset(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.MlmdDataset, error) -} - -type executableSchema struct { - resolvers ResolverRoot - directives DirectiveRoot - complexity ComplexityRoot -} - -func (e *executableSchema) Schema() *ast.Schema { - return parsedSchema -} - -func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { - ec := executionContext{nil, e, 0, 0, nil} - _ = ec - switch typeName + "." + field { - - case "Artifact.createTimeSinceEpoch": - if e.complexity.Artifact.CreateTimeSinceEpoch == nil { - break - } - - return e.complexity.Artifact.CreateTimeSinceEpoch(childComplexity), true - - case "Artifact.externalId": - if e.complexity.Artifact.ExternalID == nil { - break - } - - return e.complexity.Artifact.ExternalID(childComplexity), true - - case "Artifact.id": - if e.complexity.Artifact.ID == nil { - break - } - - return e.complexity.Artifact.ID(childComplexity), true - - case "Artifact.lastUpdateTimeSinceEpoch": - if e.complexity.Artifact.LastUpdateTimeSinceEpoch == nil { - break - } - - return e.complexity.Artifact.LastUpdateTimeSinceEpoch(childComplexity), true - - case "Artifact.name": - if e.complexity.Artifact.Name == nil { - break - } - - return e.complexity.Artifact.Name(childComplexity), true - - case "Artifact.properties": - if e.complexity.Artifact.Properties == nil { - break - } - - return e.complexity.Artifact.Properties(childComplexity), true - - case "Artifact.state": - if e.complexity.Artifact.State == nil { - break - } - - return e.complexity.Artifact.State(childComplexity), true - - case "Artifact.type": - if e.complexity.Artifact.Type == nil { - break - } - - args, err := ec.field_Artifact_type_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Artifact.Type(childComplexity, args["filter"].(*graph.InstanceFilter)), true - - case "Artifact.typeId": - if e.complexity.Artifact.TypeID == nil { - break - } - - return e.complexity.Artifact.TypeID(childComplexity), true - - case "Artifact.uri": - if e.complexity.Artifact.URI == nil { - break - } - - return e.complexity.Artifact.URI(childComplexity), true - - case "ArtifactProperty.artifactId": - if e.complexity.ArtifactProperty.ArtifactID == nil { - break - } - - return e.complexity.ArtifactProperty.ArtifactID(childComplexity), true - - case "ArtifactProperty.isCustomProperty": - if e.complexity.ArtifactProperty.IsCustomProperty == nil { - break - } - - return e.complexity.ArtifactProperty.IsCustomProperty(childComplexity), true - - case "ArtifactProperty.name": - if e.complexity.ArtifactProperty.Name == nil { - break - } - - return e.complexity.ArtifactProperty.Name(childComplexity), true - - case "ArtifactProperty.propertyValue": - if e.complexity.ArtifactProperty.PropertyValue == nil { - break - } - - return e.complexity.ArtifactProperty.PropertyValue(childComplexity), true - - case "ArtifactType.description": - if e.complexity.ArtifactType.Description == nil { - break - } - - return e.complexity.ArtifactType.Description(childComplexity), true - - case "ArtifactType.externalId": - if e.complexity.ArtifactType.ExternalID == nil { - break - } - - return e.complexity.ArtifactType.ExternalID(childComplexity), true - - case "ArtifactType.id": - if e.complexity.ArtifactType.ID == nil { - break - } - - return e.complexity.ArtifactType.ID(childComplexity), true - - case "ArtifactType.name": - if e.complexity.ArtifactType.Name == nil { - break - } - - return e.complexity.ArtifactType.Name(childComplexity), true - - case "ArtifactType.properties": - if e.complexity.ArtifactType.Properties == nil { - break - } - - return e.complexity.ArtifactType.Properties(childComplexity), true - - case "ArtifactType.typeKind": - if e.complexity.ArtifactType.TypeKind == nil { - break - } - - return e.complexity.ArtifactType.TypeKind(childComplexity), true - - case "ArtifactType.version": - if e.complexity.ArtifactType.Version == nil { - break - } - - return e.complexity.ArtifactType.Version(childComplexity), true - - case "BoolValue.value": - if e.complexity.BoolValue.Value == nil { - break - } - - return e.complexity.BoolValue.Value(childComplexity), true - - case "Context.associations": - if e.complexity.Context.Associations == nil { - break - } - - return e.complexity.Context.Associations(childComplexity), true - - case "Context.attributions": - if e.complexity.Context.Attributions == nil { - break - } - - return e.complexity.Context.Attributions(childComplexity), true - - case "Context.children": - if e.complexity.Context.Children == nil { - break - } - - return e.complexity.Context.Children(childComplexity), true - - case "Context.createTimeSinceEpoch": - if e.complexity.Context.CreateTimeSinceEpoch == nil { - break - } - - return e.complexity.Context.CreateTimeSinceEpoch(childComplexity), true - - case "Context.externalId": - if e.complexity.Context.ExternalID == nil { - break - } - - return e.complexity.Context.ExternalID(childComplexity), true - - case "Context.id": - if e.complexity.Context.ID == nil { - break - } - - return e.complexity.Context.ID(childComplexity), true - - case "Context.lastUpdateTimeSinceEpoch": - if e.complexity.Context.LastUpdateTimeSinceEpoch == nil { - break - } - - return e.complexity.Context.LastUpdateTimeSinceEpoch(childComplexity), true - - case "Context.name": - if e.complexity.Context.Name == nil { - break - } - - return e.complexity.Context.Name(childComplexity), true - - case "Context.parent": - if e.complexity.Context.Parent == nil { - break - } - - return e.complexity.Context.Parent(childComplexity), true - - case "Context.properties": - if e.complexity.Context.Properties == nil { - break - } - - return e.complexity.Context.Properties(childComplexity), true - - case "Context.type": - if e.complexity.Context.Type == nil { - break - } - - return e.complexity.Context.Type(childComplexity), true - - case "Context.typeId": - if e.complexity.Context.TypeID == nil { - break - } - - return e.complexity.Context.TypeID(childComplexity), true - - case "ContextProperty.contextId": - if e.complexity.ContextProperty.ContextID == nil { - break - } - - return e.complexity.ContextProperty.ContextID(childComplexity), true - - case "ContextProperty.isCustomProperty": - if e.complexity.ContextProperty.IsCustomProperty == nil { - break - } - - return e.complexity.ContextProperty.IsCustomProperty(childComplexity), true - - case "ContextProperty.name": - if e.complexity.ContextProperty.Name == nil { - break - } - - return e.complexity.ContextProperty.Name(childComplexity), true - - case "ContextProperty.propertyValue": - if e.complexity.ContextProperty.PropertyValue == nil { - break - } - - return e.complexity.ContextProperty.PropertyValue(childComplexity), true - - case "ContextType.description": - if e.complexity.ContextType.Description == nil { - break - } - - return e.complexity.ContextType.Description(childComplexity), true - - case "ContextType.externalId": - if e.complexity.ContextType.ExternalID == nil { - break - } - - return e.complexity.ContextType.ExternalID(childComplexity), true - - case "ContextType.id": - if e.complexity.ContextType.ID == nil { - break - } - - return e.complexity.ContextType.ID(childComplexity), true - - case "ContextType.name": - if e.complexity.ContextType.Name == nil { - break - } - - return e.complexity.ContextType.Name(childComplexity), true - - case "ContextType.properties": - if e.complexity.ContextType.Properties == nil { - break - } - - return e.complexity.ContextType.Properties(childComplexity), true - - case "ContextType.typeKind": - if e.complexity.ContextType.TypeKind == nil { - break - } - - return e.complexity.ContextType.TypeKind(childComplexity), true - - case "ContextType.version": - if e.complexity.ContextType.Version == nil { - break - } - - return e.complexity.ContextType.Version(childComplexity), true - - case "DoubleValue.value": - if e.complexity.DoubleValue.Value == nil { - break - } - - return e.complexity.DoubleValue.Value(childComplexity), true - - case "Event.artifact": - if e.complexity.Event.Artifact == nil { - break - } - - return e.complexity.Event.Artifact(childComplexity), true - - case "Event.artifactId": - if e.complexity.Event.ArtifactID == nil { - break - } - - return e.complexity.Event.ArtifactID(childComplexity), true - - case "Event.execution": - if e.complexity.Event.Execution == nil { - break - } - - return e.complexity.Event.Execution(childComplexity), true - - case "Event.executionId": - if e.complexity.Event.ExecutionID == nil { - break - } - - return e.complexity.Event.ExecutionID(childComplexity), true - - case "Event.id": - if e.complexity.Event.ID == nil { - break - } - - return e.complexity.Event.ID(childComplexity), true - - case "Event.millisecondsSinceEpoch": - if e.complexity.Event.MillisecondsSinceEpoch == nil { - break - } - - return e.complexity.Event.MillisecondsSinceEpoch(childComplexity), true - - case "Event.type": - if e.complexity.Event.Type == nil { - break - } - - return e.complexity.Event.Type(childComplexity), true - - case "EventPath.eventId": - if e.complexity.EventPath.EventID == nil { - break - } - - return e.complexity.EventPath.EventID(childComplexity), true - - case "EventPath.isIndexStep": - if e.complexity.EventPath.IsIndexStep == nil { - break - } - - return e.complexity.EventPath.IsIndexStep(childComplexity), true - - case "EventPath.stepIndex": - if e.complexity.EventPath.StepIndex == nil { - break - } - - return e.complexity.EventPath.StepIndex(childComplexity), true - - case "EventPath.stepKey": - if e.complexity.EventPath.StepKey == nil { - break - } - - return e.complexity.EventPath.StepKey(childComplexity), true - - case "Execution.createTimeSinceEpoch": - if e.complexity.Execution.CreateTimeSinceEpoch == nil { - break - } - - return e.complexity.Execution.CreateTimeSinceEpoch(childComplexity), true - - case "Execution.externalId": - if e.complexity.Execution.ExternalID == nil { - break - } - - return e.complexity.Execution.ExternalID(childComplexity), true - - case "Execution.id": - if e.complexity.Execution.ID == nil { - break - } - - return e.complexity.Execution.ID(childComplexity), true - - case "Execution.lastKnownState": - if e.complexity.Execution.LastKnownState == nil { - break - } - - return e.complexity.Execution.LastKnownState(childComplexity), true - - case "Execution.lastUpdateTimeSinceEpoch": - if e.complexity.Execution.LastUpdateTimeSinceEpoch == nil { - break - } - - return e.complexity.Execution.LastUpdateTimeSinceEpoch(childComplexity), true - - case "Execution.name": - if e.complexity.Execution.Name == nil { - break - } - - return e.complexity.Execution.Name(childComplexity), true - - case "Execution.properties": - if e.complexity.Execution.Properties == nil { - break - } - - return e.complexity.Execution.Properties(childComplexity), true - - case "Execution.type": - if e.complexity.Execution.Type == nil { - break - } - - return e.complexity.Execution.Type(childComplexity), true - - case "Execution.typeId": - if e.complexity.Execution.TypeID == nil { - break - } - - return e.complexity.Execution.TypeID(childComplexity), true - - case "ExecutionProperty.executionId": - if e.complexity.ExecutionProperty.ExecutionID == nil { - break - } - - return e.complexity.ExecutionProperty.ExecutionID(childComplexity), true - - case "ExecutionProperty.isCustomProperty": - if e.complexity.ExecutionProperty.IsCustomProperty == nil { - break - } - - return e.complexity.ExecutionProperty.IsCustomProperty(childComplexity), true - - case "ExecutionProperty.name": - if e.complexity.ExecutionProperty.Name == nil { - break - } - - return e.complexity.ExecutionProperty.Name(childComplexity), true - - case "ExecutionProperty.propertyValue": - if e.complexity.ExecutionProperty.PropertyValue == nil { - break - } - - return e.complexity.ExecutionProperty.PropertyValue(childComplexity), true - - case "ExecutionType.description": - if e.complexity.ExecutionType.Description == nil { - break - } - - return e.complexity.ExecutionType.Description(childComplexity), true - - case "ExecutionType.externalId": - if e.complexity.ExecutionType.ExternalID == nil { - break - } - - return e.complexity.ExecutionType.ExternalID(childComplexity), true - - case "ExecutionType.id": - if e.complexity.ExecutionType.ID == nil { - break - } - - return e.complexity.ExecutionType.ID(childComplexity), true - - case "ExecutionType.inputType": - if e.complexity.ExecutionType.InputType == nil { - break - } - - return e.complexity.ExecutionType.InputType(childComplexity), true - - case "ExecutionType.name": - if e.complexity.ExecutionType.Name == nil { - break - } - - return e.complexity.ExecutionType.Name(childComplexity), true - - case "ExecutionType.outputType": - if e.complexity.ExecutionType.OutputType == nil { - break - } - - return e.complexity.ExecutionType.OutputType(childComplexity), true - - case "ExecutionType.properties": - if e.complexity.ExecutionType.Properties == nil { - break - } - - return e.complexity.ExecutionType.Properties(childComplexity), true - - case "ExecutionType.typeKind": - if e.complexity.ExecutionType.TypeKind == nil { - break - } - - return e.complexity.ExecutionType.TypeKind(childComplexity), true - - case "ExecutionType.version": - if e.complexity.ExecutionType.Version == nil { - break - } - - return e.complexity.ExecutionType.Version(childComplexity), true - - case "IntValue.value": - if e.complexity.IntValue.Value == nil { - break - } - - return e.complexity.IntValue.Value(childComplexity), true - - case "MlmdDataset.description": - if e.complexity.MlmdDataset.Description == nil { - break - } - - return e.complexity.MlmdDataset.Description(childComplexity), true - - case "MlmdDataset.externalId": - if e.complexity.MlmdDataset.ExternalID == nil { - break - } - - return e.complexity.MlmdDataset.ExternalID(childComplexity), true - - case "MlmdDataset.id": - if e.complexity.MlmdDataset.ID == nil { - break - } - - return e.complexity.MlmdDataset.ID(childComplexity), true - - case "MlmdDataset.name": - if e.complexity.MlmdDataset.Name == nil { - break - } - - return e.complexity.MlmdDataset.Name(childComplexity), true - - case "MlmdDataset.properties": - if e.complexity.MlmdDataset.Properties == nil { - break - } - - return e.complexity.MlmdDataset.Properties(childComplexity), true - - case "MlmdDataset.typeKind": - if e.complexity.MlmdDataset.TypeKind == nil { - break - } - - return e.complexity.MlmdDataset.TypeKind(childComplexity), true - - case "MlmdDataset.version": - if e.complexity.MlmdDataset.Version == nil { - break - } - - return e.complexity.MlmdDataset.Version(childComplexity), true - - case "MlmdDeploy.description": - if e.complexity.MlmdDeploy.Description == nil { - break - } - - return e.complexity.MlmdDeploy.Description(childComplexity), true - - case "MlmdDeploy.externalId": - if e.complexity.MlmdDeploy.ExternalID == nil { - break - } - - return e.complexity.MlmdDeploy.ExternalID(childComplexity), true - - case "MlmdDeploy.id": - if e.complexity.MlmdDeploy.ID == nil { - break - } - - return e.complexity.MlmdDeploy.ID(childComplexity), true - - case "MlmdDeploy.inputType": - if e.complexity.MlmdDeploy.InputType == nil { - break - } - - return e.complexity.MlmdDeploy.InputType(childComplexity), true - - case "MlmdDeploy.name": - if e.complexity.MlmdDeploy.Name == nil { - break - } - - return e.complexity.MlmdDeploy.Name(childComplexity), true - - case "MlmdDeploy.outputType": - if e.complexity.MlmdDeploy.OutputType == nil { - break - } - - return e.complexity.MlmdDeploy.OutputType(childComplexity), true - - case "MlmdDeploy.properties": - if e.complexity.MlmdDeploy.Properties == nil { - break - } - - return e.complexity.MlmdDeploy.Properties(childComplexity), true - - case "MlmdDeploy.typeKind": - if e.complexity.MlmdDeploy.TypeKind == nil { - break - } - - return e.complexity.MlmdDeploy.TypeKind(childComplexity), true - - case "MlmdDeploy.version": - if e.complexity.MlmdDeploy.Version == nil { - break - } - - return e.complexity.MlmdDeploy.Version(childComplexity), true - - case "MlmdEvaluate.description": - if e.complexity.MlmdEvaluate.Description == nil { - break - } - - return e.complexity.MlmdEvaluate.Description(childComplexity), true - - case "MlmdEvaluate.externalId": - if e.complexity.MlmdEvaluate.ExternalID == nil { - break - } - - return e.complexity.MlmdEvaluate.ExternalID(childComplexity), true - - case "MlmdEvaluate.id": - if e.complexity.MlmdEvaluate.ID == nil { - break - } - - return e.complexity.MlmdEvaluate.ID(childComplexity), true - - case "MlmdEvaluate.inputType": - if e.complexity.MlmdEvaluate.InputType == nil { - break - } - - return e.complexity.MlmdEvaluate.InputType(childComplexity), true - - case "MlmdEvaluate.name": - if e.complexity.MlmdEvaluate.Name == nil { - break - } - - return e.complexity.MlmdEvaluate.Name(childComplexity), true - - case "MlmdEvaluate.outputType": - if e.complexity.MlmdEvaluate.OutputType == nil { - break - } - - return e.complexity.MlmdEvaluate.OutputType(childComplexity), true - - case "MlmdEvaluate.properties": - if e.complexity.MlmdEvaluate.Properties == nil { - break - } - - return e.complexity.MlmdEvaluate.Properties(childComplexity), true - - case "MlmdEvaluate.typeKind": - if e.complexity.MlmdEvaluate.TypeKind == nil { - break - } - - return e.complexity.MlmdEvaluate.TypeKind(childComplexity), true - - case "MlmdEvaluate.version": - if e.complexity.MlmdEvaluate.Version == nil { - break - } - - return e.complexity.MlmdEvaluate.Version(childComplexity), true - - case "MlmdMetrics.description": - if e.complexity.MlmdMetrics.Description == nil { - break - } - - return e.complexity.MlmdMetrics.Description(childComplexity), true - - case "MlmdMetrics.externalId": - if e.complexity.MlmdMetrics.ExternalID == nil { - break - } - - return e.complexity.MlmdMetrics.ExternalID(childComplexity), true - - case "MlmdMetrics.id": - if e.complexity.MlmdMetrics.ID == nil { - break - } - - return e.complexity.MlmdMetrics.ID(childComplexity), true - - case "MlmdMetrics.name": - if e.complexity.MlmdMetrics.Name == nil { - break - } - - return e.complexity.MlmdMetrics.Name(childComplexity), true - - case "MlmdMetrics.properties": - if e.complexity.MlmdMetrics.Properties == nil { - break - } - - return e.complexity.MlmdMetrics.Properties(childComplexity), true - - case "MlmdMetrics.typeKind": - if e.complexity.MlmdMetrics.TypeKind == nil { - break - } - - return e.complexity.MlmdMetrics.TypeKind(childComplexity), true - - case "MlmdMetrics.version": - if e.complexity.MlmdMetrics.Version == nil { - break - } - - return e.complexity.MlmdMetrics.Version(childComplexity), true - - case "MlmdModel.description": - if e.complexity.MlmdModel.Description == nil { - break - } - - return e.complexity.MlmdModel.Description(childComplexity), true - - case "MlmdModel.externalId": - if e.complexity.MlmdModel.ExternalID == nil { - break - } - - return e.complexity.MlmdModel.ExternalID(childComplexity), true - - case "MlmdModel.id": - if e.complexity.MlmdModel.ID == nil { - break - } - - return e.complexity.MlmdModel.ID(childComplexity), true - - case "MlmdModel.name": - if e.complexity.MlmdModel.Name == nil { - break - } - - return e.complexity.MlmdModel.Name(childComplexity), true - - case "MlmdModel.properties": - if e.complexity.MlmdModel.Properties == nil { - break - } - - return e.complexity.MlmdModel.Properties(childComplexity), true - - case "MlmdModel.typeKind": - if e.complexity.MlmdModel.TypeKind == nil { - break - } - - return e.complexity.MlmdModel.TypeKind(childComplexity), true - - case "MlmdModel.version": - if e.complexity.MlmdModel.Version == nil { - break - } - - return e.complexity.MlmdModel.Version(childComplexity), true - - case "MlmdProcess.description": - if e.complexity.MlmdProcess.Description == nil { - break - } - - return e.complexity.MlmdProcess.Description(childComplexity), true - - case "MlmdProcess.externalId": - if e.complexity.MlmdProcess.ExternalID == nil { - break - } - - return e.complexity.MlmdProcess.ExternalID(childComplexity), true - - case "MlmdProcess.id": - if e.complexity.MlmdProcess.ID == nil { - break - } - - return e.complexity.MlmdProcess.ID(childComplexity), true - - case "MlmdProcess.inputType": - if e.complexity.MlmdProcess.InputType == nil { - break - } - - return e.complexity.MlmdProcess.InputType(childComplexity), true - - case "MlmdProcess.name": - if e.complexity.MlmdProcess.Name == nil { - break - } - - return e.complexity.MlmdProcess.Name(childComplexity), true - - case "MlmdProcess.outputType": - if e.complexity.MlmdProcess.OutputType == nil { - break - } - - return e.complexity.MlmdProcess.OutputType(childComplexity), true - - case "MlmdProcess.properties": - if e.complexity.MlmdProcess.Properties == nil { - break - } - - return e.complexity.MlmdProcess.Properties(childComplexity), true - - case "MlmdProcess.typeKind": - if e.complexity.MlmdProcess.TypeKind == nil { - break - } - - return e.complexity.MlmdProcess.TypeKind(childComplexity), true - - case "MlmdProcess.version": - if e.complexity.MlmdProcess.Version == nil { - break - } - - return e.complexity.MlmdProcess.Version(childComplexity), true - - case "MlmdStatistics.description": - if e.complexity.MlmdStatistics.Description == nil { - break - } - - return e.complexity.MlmdStatistics.Description(childComplexity), true - - case "MlmdStatistics.externalId": - if e.complexity.MlmdStatistics.ExternalID == nil { - break - } - - return e.complexity.MlmdStatistics.ExternalID(childComplexity), true - - case "MlmdStatistics.id": - if e.complexity.MlmdStatistics.ID == nil { - break - } - - return e.complexity.MlmdStatistics.ID(childComplexity), true - - case "MlmdStatistics.name": - if e.complexity.MlmdStatistics.Name == nil { - break - } - - return e.complexity.MlmdStatistics.Name(childComplexity), true - - case "MlmdStatistics.properties": - if e.complexity.MlmdStatistics.Properties == nil { - break - } - - return e.complexity.MlmdStatistics.Properties(childComplexity), true - - case "MlmdStatistics.typeKind": - if e.complexity.MlmdStatistics.TypeKind == nil { - break - } - - return e.complexity.MlmdStatistics.TypeKind(childComplexity), true - - case "MlmdStatistics.version": - if e.complexity.MlmdStatistics.Version == nil { - break - } - - return e.complexity.MlmdStatistics.Version(childComplexity), true - - case "MlmdTrain.description": - if e.complexity.MlmdTrain.Description == nil { - break - } - - return e.complexity.MlmdTrain.Description(childComplexity), true - - case "MlmdTrain.externalId": - if e.complexity.MlmdTrain.ExternalID == nil { - break - } - - return e.complexity.MlmdTrain.ExternalID(childComplexity), true - - case "MlmdTrain.id": - if e.complexity.MlmdTrain.ID == nil { - break - } - - return e.complexity.MlmdTrain.ID(childComplexity), true - - case "MlmdTrain.inputType": - if e.complexity.MlmdTrain.InputType == nil { - break - } - - return e.complexity.MlmdTrain.InputType(childComplexity), true - - case "MlmdTrain.name": - if e.complexity.MlmdTrain.Name == nil { - break - } - - return e.complexity.MlmdTrain.Name(childComplexity), true - - case "MlmdTrain.outputType": - if e.complexity.MlmdTrain.OutputType == nil { - break - } - - return e.complexity.MlmdTrain.OutputType(childComplexity), true - - case "MlmdTrain.properties": - if e.complexity.MlmdTrain.Properties == nil { - break - } - - return e.complexity.MlmdTrain.Properties(childComplexity), true - - case "MlmdTrain.typeKind": - if e.complexity.MlmdTrain.TypeKind == nil { - break - } - - return e.complexity.MlmdTrain.TypeKind(childComplexity), true - - case "MlmdTrain.version": - if e.complexity.MlmdTrain.Version == nil { - break - } - - return e.complexity.MlmdTrain.Version(childComplexity), true - - case "MlmdTransform.description": - if e.complexity.MlmdTransform.Description == nil { - break - } - - return e.complexity.MlmdTransform.Description(childComplexity), true - - case "MlmdTransform.externalId": - if e.complexity.MlmdTransform.ExternalID == nil { - break - } - - return e.complexity.MlmdTransform.ExternalID(childComplexity), true - - case "MlmdTransform.id": - if e.complexity.MlmdTransform.ID == nil { - break - } - - return e.complexity.MlmdTransform.ID(childComplexity), true - - case "MlmdTransform.inputType": - if e.complexity.MlmdTransform.InputType == nil { - break - } - - return e.complexity.MlmdTransform.InputType(childComplexity), true - - case "MlmdTransform.name": - if e.complexity.MlmdTransform.Name == nil { - break - } - - return e.complexity.MlmdTransform.Name(childComplexity), true - - case "MlmdTransform.outputType": - if e.complexity.MlmdTransform.OutputType == nil { - break - } - - return e.complexity.MlmdTransform.OutputType(childComplexity), true - - case "MlmdTransform.properties": - if e.complexity.MlmdTransform.Properties == nil { - break - } - - return e.complexity.MlmdTransform.Properties(childComplexity), true - - case "MlmdTransform.typeKind": - if e.complexity.MlmdTransform.TypeKind == nil { - break - } - - return e.complexity.MlmdTransform.TypeKind(childComplexity), true - - case "MlmdTransform.version": - if e.complexity.MlmdTransform.Version == nil { - break - } - - return e.complexity.MlmdTransform.Version(childComplexity), true - - case "Query.artifactTypes": - if e.complexity.Query.ArtifactTypes == nil { - break - } - - args, err := ec.field_Query_artifactTypes_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.ArtifactTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true - - case "Query.artifacts": - if e.complexity.Query.Artifacts == nil { - break - } - - args, err := ec.field_Query_artifacts_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.Artifacts(childComplexity, args["filter"].(*graph.InstanceFilter)), true - - case "Query.contextTypes": - if e.complexity.Query.ContextTypes == nil { - break - } - - args, err := ec.field_Query_contextTypes_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.ContextTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true - - case "Query.contexts": - if e.complexity.Query.Contexts == nil { - break - } - - args, err := ec.field_Query_contexts_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.Contexts(childComplexity, args["filter"].(*graph.InstanceFilter)), true - - case "Query.events": - if e.complexity.Query.Events == nil { - break - } - - return e.complexity.Query.Events(childComplexity), true - - case "Query.executionTypes": - if e.complexity.Query.ExecutionTypes == nil { - break - } - - args, err := ec.field_Query_executionTypes_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.ExecutionTypes(childComplexity, args["filter"].(*graph.TypeFilter)), true - - case "Query.executions": - if e.complexity.Query.Executions == nil { - break - } - - args, err := ec.field_Query_executions_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.Executions(childComplexity, args["filter"].(*graph.InstanceFilter)), true - - case "Query.mlmdDataset": - if e.complexity.Query.MlmdDataset == nil { - break - } - - args, err := ec.field_Query_mlmdDataset_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.MlmdDataset(childComplexity, args["filter"].(*graph.InstanceFilter)), true - - case "Query.types": - if e.complexity.Query.Types == nil { - break - } - - args, err := ec.field_Query_types_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.Types(childComplexity, args["filter"].(*graph.TypeFilter)), true - - case "StringValue.value": - if e.complexity.StringValue.Value == nil { - break - } - - return e.complexity.StringValue.Value(childComplexity), true - - case "TypeProperty.dataType": - if e.complexity.TypeProperty.DataType == nil { - break - } - - return e.complexity.TypeProperty.DataType(childComplexity), true - - case "TypeProperty.name": - if e.complexity.TypeProperty.Name == nil { - break - } - - return e.complexity.TypeProperty.Name(childComplexity), true - - case "TypeProperty.typeId": - if e.complexity.TypeProperty.TypeID == nil { - break - } - - return e.complexity.TypeProperty.TypeID(childComplexity), true - - } - return 0, false -} - -func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { - rc := graphql.GetOperationContext(ctx) - ec := executionContext{rc, e, 0, 0, make(chan graphql.DeferredResult)} - inputUnmarshalMap := graphql.BuildUnmarshalerMap( - ec.unmarshalInputInstanceFilter, - ec.unmarshalInputTypeFilter, - ) - first := true - - switch rc.Operation.Operation { - case ast.Query: - return func(ctx context.Context) *graphql.Response { - var response graphql.Response - var data graphql.Marshaler - if first { - first = false - ctx = graphql.WithUnmarshalerMap(ctx, inputUnmarshalMap) - data = ec._Query(ctx, rc.Operation.SelectionSet) - } else { - if atomic.LoadInt32(&ec.pendingDeferred) > 0 { - result := <-ec.deferredResults - atomic.AddInt32(&ec.pendingDeferred, -1) - data = result.Result - response.Path = result.Path - response.Label = result.Label - response.Errors = result.Errors - } else { - return nil - } - } - var buf bytes.Buffer - data.MarshalGQL(&buf) - response.Data = buf.Bytes() - if atomic.LoadInt32(&ec.deferred) > 0 { - hasNext := atomic.LoadInt32(&ec.pendingDeferred) > 0 - response.HasNext = &hasNext - } - - return &response - } - - default: - return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation")) - } -} - -type executionContext struct { - *graphql.OperationContext - *executableSchema - deferred int32 - pendingDeferred int32 - deferredResults chan graphql.DeferredResult -} - -func (ec *executionContext) processDeferredGroup(dg graphql.DeferredGroup) { - atomic.AddInt32(&ec.pendingDeferred, 1) - go func() { - ctx := graphql.WithFreshResponseContext(dg.Context) - dg.FieldSet.Dispatch(ctx) - ds := graphql.DeferredResult{ - Path: dg.Path, - Label: dg.Label, - Result: dg.FieldSet, - Errors: graphql.GetErrors(ctx), - } - // null fields should bubble up - if dg.FieldSet.Invalids > 0 { - ds.Result = graphql.Null - } - ec.deferredResults <- ds - }() -} - -func (ec *executionContext) introspectSchema() (*introspection.Schema, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapSchema(parsedSchema), nil -} - -func (ec *executionContext) introspectType(name string) (*introspection.Type, error) { - if ec.DisableIntrospection { - return nil, errors.New("introspection disabled") - } - return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil -} - -var sources = []*ast.Source{ - {Name: "../../../api/graphql/base-schema.graphqls", Input: `type Artifact { - id: ID - typeId: ID! - uri: String! - state: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type(filter: InstanceFilter): ArtifactType! - properties : [ArtifactProperty!] -} - -type ArtifactProperty { - artifactId: ID - name: String - isCustomProperty: Boolean! - propertyValue: Value! -} - -type Context { - id: ID - typeId: ID! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ContextType! - parent: Context - children: [Context] - attributions: [Artifact!] - associations: [Execution!] - properties: [ContextProperty!] -} - -type ContextProperty { - contextId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} - -type Event { - id: ID - artifactId: ID! - executionId: ID! - type: Int! - artifact: Artifact - execution: Execution - millisecondsSinceEpoch: Int! -} - -type EventPath { - eventId: ID! - isIndexStep: Int! - stepIndex: Int! - stepKey: String! -} - -type Execution { - id: ID - typeId: ID! - lastKnownState: Int! - name: String! - externalId: String - createTimeSinceEpoch: Int! - lastUpdateTimeSinceEpoch: Int! - type: ExecutionType! - properties: [ExecutionProperty!] -} - -type ExecutionProperty { - executionId: ID - name: String! - isCustomProperty: Int! - propertyValue: Value! -} - -union Value = IntValue | DoubleValue | StringValue | BoolValue - -type IntValue { - value: Int! -} - -type DoubleValue { - value: Float! -} - -type StringValue { - value: String! -} - -type BoolValue { - value: Boolean! -} - -interface Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type TypeProperty { - typeId: ID! - name: String! - dataType: Int! -} - -interface ArtifactTypeInterface implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type ArtifactType implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -interface ContextTypeInterface implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type ContextType implements ContextTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -interface ExecutionTypeInterface implements Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type ExecutionType implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} -`, BuiltIn: false}, - {Name: "../../../api/graphql/ml-metadata.graphqls", Input: `type MlmdDataset implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdModel implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdMetrics implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdStatistics implements ArtifactTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - properties: [TypeProperty!] -} - -type MlmdTrain implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdTransform implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdProcess implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdEvaluate implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} - -type MlmdDeploy implements ExecutionTypeInterface & Type { - id: ID - name: String! - version: String! - typeKind: Int! - description: String! - externalId: String - inputType: String! - outputType: String! - properties: [TypeProperty!] -} -`, BuiltIn: false}, - {Name: "../../../api/graphql/schema.graphqls", Input: `input TypeFilter { - ids: [ID!] - names: [String!] - versions: [String!] - externalIds: [String!] -} - -input InstanceFilter { - ids: [ID!] - typeIds: [ID!] - names: [String!] - externalIds: [String!] -} - -type Query { - types(filter: TypeFilter): [Type!] - artifactTypes(filter: TypeFilter): [ArtifactType!] - contextTypes(filter: TypeFilter): [ContextType!] - executionTypes(filter: TypeFilter): [ExecutionType!] - artifacts(filter: InstanceFilter): [Artifact!] - contexts(filter: InstanceFilter): [Context!] - executions(filter: InstanceFilter): [Execution!] - events: [Event!] - mlmdDataset(filter: InstanceFilter): [MlmdDataset!] -} -`, BuiltIn: false}, -} -var parsedSchema = gqlparser.MustLoadSchema(sources...) - -// endregion ************************** generated!.gotpl ************************** - -// region ***************************** args.gotpl ***************************** - -func (ec *executionContext) field_Artifact_type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 string - if tmp, ok := rawArgs["name"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) - arg0, err = ec.unmarshalNString2string(ctx, tmp) - if err != nil { - return nil, err - } - } - args["name"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_artifactTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_artifacts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_contextTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_contexts_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_executionTypes_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_executions_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_mlmdDataset_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.InstanceFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_types_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 *graph.TypeFilter - if tmp, ok := rawArgs["filter"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("filter")) - arg0, err = ec.unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx, tmp) - if err != nil { - return nil, err - } - } - args["filter"] = arg0 - return args, nil -} - -func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 bool - if tmp, ok := rawArgs["includeDeprecated"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) - arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) - if err != nil { - return nil, err - } - } - args["includeDeprecated"] = arg0 - return args, nil -} - -func (ec *executionContext) field___Type_fields_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 bool - if tmp, ok := rawArgs["includeDeprecated"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("includeDeprecated")) - arg0, err = ec.unmarshalOBoolean2bool(ctx, tmp) - if err != nil { - return nil, err - } - } - args["includeDeprecated"] = arg0 - return args, nil -} - -// endregion ***************************** args.gotpl ***************************** - -// region ************************** directives.gotpl ************************** - -// endregion ************************** directives.gotpl ************************** - -// region **************************** field.gotpl ***************************** - -func (ec *executionContext) _Artifact_id(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_typeId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_uri(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_uri(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.URI, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_uri(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_state(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_state(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.State, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_state(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_name(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.CreateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.LastUpdateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Artifact_type(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Artifact().Type(rctx, obj, fc.Args["filter"].(*graph.InstanceFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*graph.ArtifactType) - fc.Result = res - return ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ArtifactType_id(ctx, field) - case "name": - return ec.fieldContext_ArtifactType_name(ctx, field) - case "version": - return ec.fieldContext_ArtifactType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ArtifactType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ArtifactType_description(ctx, field) - case "externalId": - return ec.fieldContext_ArtifactType_externalId(ctx, field) - case "properties": - return ec.fieldContext_ArtifactType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ArtifactType", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Artifact_type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Artifact_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Artifact) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Artifact_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.ArtifactProperty) - fc.Result = res - return ec.marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Artifact_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Artifact", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "artifactId": - return ec.fieldContext_ArtifactProperty_artifactId(ctx, field) - case "name": - return ec.fieldContext_ArtifactProperty_name(ctx, field) - case "isCustomProperty": - return ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) - case "propertyValue": - return ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ArtifactProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_artifactId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ArtifactID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactProperty_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_isCustomProperty(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsCustomProperty, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(bool) - fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactProperty_propertyValue(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.PropertyValue, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(graph.Value) - fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Value does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ArtifactType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ArtifactType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ArtifactType_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ArtifactType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ArtifactType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _BoolValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.BoolValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_BoolValue_value(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Value, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(bool) - fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_BoolValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "BoolValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_id(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_typeId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_name(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.CreateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.LastUpdateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_type(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Type, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*graph.ContextType) - fc.Result = res - return ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ContextType_id(ctx, field) - case "name": - return ec.fieldContext_ContextType_name(ctx, field) - case "version": - return ec.fieldContext_ContextType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ContextType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ContextType_description(ctx, field) - case "externalId": - return ec.fieldContext_ContextType_externalId(ctx, field) - case "properties": - return ec.fieldContext_ContextType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ContextType", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_parent(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_parent(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Parent, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*graph.Context) - fc.Result = res - return ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_parent(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Context_id(ctx, field) - case "typeId": - return ec.fieldContext_Context_typeId(ctx, field) - case "name": - return ec.fieldContext_Context_name(ctx, field) - case "externalId": - return ec.fieldContext_Context_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Context_type(ctx, field) - case "parent": - return ec.fieldContext_Context_parent(ctx, field) - case "children": - return ec.fieldContext_Context_children(ctx, field) - case "attributions": - return ec.fieldContext_Context_attributions(ctx, field) - case "associations": - return ec.fieldContext_Context_associations(ctx, field) - case "properties": - return ec.fieldContext_Context_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_children(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_children(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Children, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.Context) - fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_children(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Context_id(ctx, field) - case "typeId": - return ec.fieldContext_Context_typeId(ctx, field) - case "name": - return ec.fieldContext_Context_name(ctx, field) - case "externalId": - return ec.fieldContext_Context_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Context_type(ctx, field) - case "parent": - return ec.fieldContext_Context_parent(ctx, field) - case "children": - return ec.fieldContext_Context_children(ctx, field) - case "attributions": - return ec.fieldContext_Context_attributions(ctx, field) - case "associations": - return ec.fieldContext_Context_associations(ctx, field) - case "properties": - return ec.fieldContext_Context_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_attributions(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_attributions(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Attributions, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.Artifact) - fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_attributions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Artifact_id(ctx, field) - case "typeId": - return ec.fieldContext_Artifact_typeId(ctx, field) - case "uri": - return ec.fieldContext_Artifact_uri(ctx, field) - case "state": - return ec.fieldContext_Artifact_state(ctx, field) - case "name": - return ec.fieldContext_Artifact_name(ctx, field) - case "externalId": - return ec.fieldContext_Artifact_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Artifact_type(ctx, field) - case "properties": - return ec.fieldContext_Artifact_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_associations(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_associations(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Associations, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.Execution) - fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_associations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Execution_id(ctx, field) - case "typeId": - return ec.fieldContext_Execution_typeId(ctx, field) - case "lastKnownState": - return ec.fieldContext_Execution_lastKnownState(ctx, field) - case "name": - return ec.fieldContext_Execution_name(ctx, field) - case "externalId": - return ec.fieldContext_Execution_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Execution_type(ctx, field) - case "properties": - return ec.fieldContext_Execution_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Context_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Context) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Context_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.ContextProperty) - fc.Result = res - return ec.marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextPropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Context_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Context", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "contextId": - return ec.fieldContext_ContextProperty_contextId(ctx, field) - case "name": - return ec.fieldContext_ContextProperty_name(ctx, field) - case "isCustomProperty": - return ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) - case "propertyValue": - return ec.fieldContext_ContextProperty_propertyValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ContextProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextProperty_contextId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_contextId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ContextID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextProperty_contextId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_isCustomProperty(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsCustomProperty, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ContextProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextProperty_propertyValue(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.PropertyValue, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(graph.Value) - fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Value does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ContextType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ContextType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ContextType_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ContextType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ContextType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _DoubleValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.DoubleValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_DoubleValue_value(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Value, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(float64) - fc.Result = res - return ec.marshalNFloat2float64(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_DoubleValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "DoubleValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Float does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Event_id(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Event_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Event", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Event_artifactId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_artifactId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ArtifactID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Event_artifactId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Event", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Event_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_executionId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExecutionID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Event_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Event", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Event_type(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Type, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Event_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Event", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Event_artifact(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_artifact(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Artifact, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*graph.Artifact) - fc.Result = res - return ec.marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Event_artifact(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Event", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Artifact_id(ctx, field) - case "typeId": - return ec.fieldContext_Artifact_typeId(ctx, field) - case "uri": - return ec.fieldContext_Artifact_uri(ctx, field) - case "state": - return ec.fieldContext_Artifact_state(ctx, field) - case "name": - return ec.fieldContext_Artifact_name(ctx, field) - case "externalId": - return ec.fieldContext_Artifact_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Artifact_type(ctx, field) - case "properties": - return ec.fieldContext_Artifact_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Event_execution(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_execution(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Execution, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*graph.Execution) - fc.Result = res - return ec.marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Event_execution(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Event", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Execution_id(ctx, field) - case "typeId": - return ec.fieldContext_Execution_typeId(ctx, field) - case "lastKnownState": - return ec.fieldContext_Execution_lastKnownState(ctx, field) - case "name": - return ec.fieldContext_Execution_name(ctx, field) - case "externalId": - return ec.fieldContext_Execution_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Execution_type(ctx, field) - case "properties": - return ec.fieldContext_Execution_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Event) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.MillisecondsSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Event_millisecondsSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Event", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _EventPath_eventId(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_eventId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.EventID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_EventPath_eventId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "EventPath", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_isIndexStep(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsIndexStep, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_EventPath_isIndexStep(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "EventPath", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _EventPath_stepIndex(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_stepIndex(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.StepIndex, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_EventPath_stepIndex(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "EventPath", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _EventPath_stepKey(ctx context.Context, field graphql.CollectedField, obj *graph.EventPath) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_EventPath_stepKey(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.StepKey, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_EventPath_stepKey(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "EventPath", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_id(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_typeId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_lastKnownState(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_lastKnownState(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.LastKnownState, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_lastKnownState(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_name(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.CreateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_createTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.LastUpdateTimeSinceEpoch, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_type(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Type, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*graph.ExecutionType) - fc.Result = res - return ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ExecutionType_id(ctx, field) - case "name": - return ec.fieldContext_ExecutionType_name(ctx, field) - case "version": - return ec.fieldContext_ExecutionType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ExecutionType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ExecutionType_description(ctx, field) - case "externalId": - return ec.fieldContext_ExecutionType_externalId(ctx, field) - case "inputType": - return ec.fieldContext_ExecutionType_inputType(ctx, field) - case "outputType": - return ec.fieldContext_ExecutionType_outputType(ctx, field) - case "properties": - return ec.fieldContext_ExecutionType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ExecutionType", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Execution_properties(ctx context.Context, field graphql.CollectedField, obj *graph.Execution) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Execution_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.ExecutionProperty) - fc.Result = res - return ec.marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Execution_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Execution", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "executionId": - return ec.fieldContext_ExecutionProperty_executionId(ctx, field) - case "name": - return ec.fieldContext_ExecutionProperty_name(ctx, field) - case "isCustomProperty": - return ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) - case "propertyValue": - return ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ExecutionProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_executionId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExecutionID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionProperty_executionId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_isCustomProperty(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsCustomProperty, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionProperty_isCustomProperty(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionProperty_propertyValue(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.PropertyValue, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(graph.Value) - fc.Result = res - return ec.marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionProperty_propertyValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Value does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_id(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_name(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_version(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_description(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_inputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_outputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OutputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _ExecutionType_properties(ctx context.Context, field graphql.CollectedField, obj *graph.ExecutionType) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_ExecutionType_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_ExecutionType_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "ExecutionType", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _IntValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.IntValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_IntValue_value(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Value, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_IntValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "IntValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDataset_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDataset_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDataset_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDataset", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDataset_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDataset_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDataset_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDataset", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDataset_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDataset_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDataset_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDataset", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDataset_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDataset_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDataset_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDataset", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDataset_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDataset_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDataset_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDataset", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDataset_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDataset_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDataset_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDataset", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDataset_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDataset) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDataset_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDataset_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDataset", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_inputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_outputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OutputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdDeploy_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdDeploy) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdDeploy_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdDeploy_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdDeploy", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_inputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_outputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OutputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdEvaluate_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdEvaluate) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdEvaluate_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdEvaluate_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdEvaluate", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdMetrics_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdMetrics_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdMetrics_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdMetrics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdMetrics_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdMetrics_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdMetrics_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdMetrics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdMetrics_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdMetrics_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdMetrics_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdMetrics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdMetrics_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdMetrics_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdMetrics_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdMetrics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdMetrics_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdMetrics_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdMetrics_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdMetrics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdMetrics_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdMetrics_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdMetrics_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdMetrics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdMetrics_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdMetrics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdMetrics_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdMetrics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdMetrics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdModel_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdModel_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdModel_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdModel", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdModel_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdModel_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdModel_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdModel", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdModel_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdModel_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdModel_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdModel", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdModel_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdModel_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdModel_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdModel", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdModel_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdModel_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdModel_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdModel", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdModel_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdModel_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdModel_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdModel", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdModel_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdModel) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdModel_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdModel_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdModel", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_inputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_outputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OutputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdProcess_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdProcess) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdProcess_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdProcess_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdProcess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdStatistics_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdStatistics_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdStatistics_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdStatistics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdStatistics_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdStatistics_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdStatistics_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdStatistics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdStatistics_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdStatistics_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdStatistics_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdStatistics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdStatistics_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdStatistics_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdStatistics_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdStatistics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdStatistics_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdStatistics_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdStatistics_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdStatistics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdStatistics_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdStatistics_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdStatistics_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdStatistics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdStatistics_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdStatistics) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdStatistics_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdStatistics_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdStatistics", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_inputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_outputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OutputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTrain_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTrain) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTrain_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTrain_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTrain", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_id(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_id(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOID2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_id(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_name(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_version(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_version(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Version, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_version(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_typeKind(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_typeKind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeKind, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_typeKind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_description(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_externalId(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_externalId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.ExternalID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_externalId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_inputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_inputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_inputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_outputType(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_outputType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OutputType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_outputType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _MlmdTransform_properties(ctx context.Context, field graphql.CollectedField, obj *graph.MlmdTransform) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_MlmdTransform_properties(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Properties, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.TypeProperty) - fc.Result = res - return ec.marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_MlmdTransform_properties(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "MlmdTransform", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "typeId": - return ec.fieldContext_TypeProperty_typeId(ctx, field) - case "name": - return ec.fieldContext_TypeProperty_name(ctx, field) - case "dataType": - return ec.fieldContext_TypeProperty_dataType(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type TypeProperty", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Query_types(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_types(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Types(rctx, fc.Args["filter"].(*graph.TypeFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]graph.Type) - fc.Result = res - return ec.marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("FieldContext.Child cannot be called on type INTERFACE") - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_types_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_artifactTypes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_artifactTypes(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().ArtifactTypes(rctx, fc.Args["filter"].(*graph.TypeFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.ArtifactType) - fc.Result = res - return ec.marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_artifactTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ArtifactType_id(ctx, field) - case "name": - return ec.fieldContext_ArtifactType_name(ctx, field) - case "version": - return ec.fieldContext_ArtifactType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ArtifactType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ArtifactType_description(ctx, field) - case "externalId": - return ec.fieldContext_ArtifactType_externalId(ctx, field) - case "properties": - return ec.fieldContext_ArtifactType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ArtifactType", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_artifactTypes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_contextTypes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_contextTypes(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().ContextTypes(rctx, fc.Args["filter"].(*graph.TypeFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.ContextType) - fc.Result = res - return ec.marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextTypeᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_contextTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ContextType_id(ctx, field) - case "name": - return ec.fieldContext_ContextType_name(ctx, field) - case "version": - return ec.fieldContext_ContextType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ContextType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ContextType_description(ctx, field) - case "externalId": - return ec.fieldContext_ContextType_externalId(ctx, field) - case "properties": - return ec.fieldContext_ContextType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ContextType", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_contextTypes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_executionTypes(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_executionTypes(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().ExecutionTypes(rctx, fc.Args["filter"].(*graph.TypeFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.ExecutionType) - fc.Result = res - return ec.marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_executionTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_ExecutionType_id(ctx, field) - case "name": - return ec.fieldContext_ExecutionType_name(ctx, field) - case "version": - return ec.fieldContext_ExecutionType_version(ctx, field) - case "typeKind": - return ec.fieldContext_ExecutionType_typeKind(ctx, field) - case "description": - return ec.fieldContext_ExecutionType_description(ctx, field) - case "externalId": - return ec.fieldContext_ExecutionType_externalId(ctx, field) - case "inputType": - return ec.fieldContext_ExecutionType_inputType(ctx, field) - case "outputType": - return ec.fieldContext_ExecutionType_outputType(ctx, field) - case "properties": - return ec.fieldContext_ExecutionType_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type ExecutionType", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_executionTypes_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_artifacts(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_artifacts(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Artifacts(rctx, fc.Args["filter"].(*graph.InstanceFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.Artifact) - fc.Result = res - return ec.marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_artifacts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Artifact_id(ctx, field) - case "typeId": - return ec.fieldContext_Artifact_typeId(ctx, field) - case "uri": - return ec.fieldContext_Artifact_uri(ctx, field) - case "state": - return ec.fieldContext_Artifact_state(ctx, field) - case "name": - return ec.fieldContext_Artifact_name(ctx, field) - case "externalId": - return ec.fieldContext_Artifact_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Artifact_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Artifact_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Artifact_type(ctx, field) - case "properties": - return ec.fieldContext_Artifact_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Artifact", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_artifacts_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_contexts(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_contexts(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Contexts(rctx, fc.Args["filter"].(*graph.InstanceFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.Context) - fc.Result = res - return ec.marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_contexts(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Context_id(ctx, field) - case "typeId": - return ec.fieldContext_Context_typeId(ctx, field) - case "name": - return ec.fieldContext_Context_name(ctx, field) - case "externalId": - return ec.fieldContext_Context_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Context_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Context_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Context_type(ctx, field) - case "parent": - return ec.fieldContext_Context_parent(ctx, field) - case "children": - return ec.fieldContext_Context_children(ctx, field) - case "attributions": - return ec.fieldContext_Context_attributions(ctx, field) - case "associations": - return ec.fieldContext_Context_associations(ctx, field) - case "properties": - return ec.fieldContext_Context_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Context", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_contexts_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_executions(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_executions(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Executions(rctx, fc.Args["filter"].(*graph.InstanceFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.Execution) - fc.Result = res - return ec.marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_executions(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Execution_id(ctx, field) - case "typeId": - return ec.fieldContext_Execution_typeId(ctx, field) - case "lastKnownState": - return ec.fieldContext_Execution_lastKnownState(ctx, field) - case "name": - return ec.fieldContext_Execution_name(ctx, field) - case "externalId": - return ec.fieldContext_Execution_externalId(ctx, field) - case "createTimeSinceEpoch": - return ec.fieldContext_Execution_createTimeSinceEpoch(ctx, field) - case "lastUpdateTimeSinceEpoch": - return ec.fieldContext_Execution_lastUpdateTimeSinceEpoch(ctx, field) - case "type": - return ec.fieldContext_Execution_type(ctx, field) - case "properties": - return ec.fieldContext_Execution_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Execution", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_executions_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_events(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_events(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().Events(rctx) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.Event) - fc.Result = res - return ec.marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEventᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_events(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_Event_id(ctx, field) - case "artifactId": - return ec.fieldContext_Event_artifactId(ctx, field) - case "executionId": - return ec.fieldContext_Event_executionId(ctx, field) - case "type": - return ec.fieldContext_Event_type(ctx, field) - case "artifact": - return ec.fieldContext_Event_artifact(ctx, field) - case "execution": - return ec.fieldContext_Event_execution(ctx, field) - case "millisecondsSinceEpoch": - return ec.fieldContext_Event_millisecondsSinceEpoch(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type Event", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _Query_mlmdDataset(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query_mlmdDataset(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().MlmdDataset(rctx, fc.Args["filter"].(*graph.InstanceFilter)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]*graph.MlmdDataset) - fc.Result = res - return ec.marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query_mlmdDataset(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "id": - return ec.fieldContext_MlmdDataset_id(ctx, field) - case "name": - return ec.fieldContext_MlmdDataset_name(ctx, field) - case "version": - return ec.fieldContext_MlmdDataset_version(ctx, field) - case "typeKind": - return ec.fieldContext_MlmdDataset_typeKind(ctx, field) - case "description": - return ec.fieldContext_MlmdDataset_description(ctx, field) - case "externalId": - return ec.fieldContext_MlmdDataset_externalId(ctx, field) - case "properties": - return ec.fieldContext_MlmdDataset_properties(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type MlmdDataset", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_mlmdDataset_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query___type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.introspectType(fc.Args["name"].(string)) - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query___type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query___type_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_Query___schema(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return ec.introspectSchema() - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*introspection.Schema) - fc.Result = res - return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_Query___schema(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "description": - return ec.fieldContext___Schema_description(ctx, field) - case "types": - return ec.fieldContext___Schema_types(ctx, field) - case "queryType": - return ec.fieldContext___Schema_queryType(ctx, field) - case "mutationType": - return ec.fieldContext___Schema_mutationType(ctx, field) - case "subscriptionType": - return ec.fieldContext___Schema_subscriptionType(ctx, field) - case "directives": - return ec.fieldContext___Schema_directives(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Schema", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) _StringValue_value(ctx context.Context, field graphql.CollectedField, obj *graph.StringValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_StringValue_value(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Value, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_StringValue_value(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "StringValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _TypeProperty_typeId(ctx context.Context, field graphql.CollectedField, obj *graph.TypeProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_TypeProperty_typeId(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.TypeID, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNID2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_TypeProperty_typeId(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "TypeProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type ID does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _TypeProperty_name(ctx context.Context, field graphql.CollectedField, obj *graph.TypeProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_TypeProperty_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_TypeProperty_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "TypeProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) _TypeProperty_dataType(ctx context.Context, field graphql.CollectedField, obj *graph.TypeProperty) (ret graphql.Marshaler) { - fc, err := ec.fieldContext_TypeProperty_dataType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.DataType, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(int) - fc.Result = res - return ec.marshalNInt2int(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext_TypeProperty_dataType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "TypeProperty", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Int does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Directive_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Directive_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Directive", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Directive_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Directive_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Directive", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Directive_locations(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Locations, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.([]string) - fc.Result = res - return ec.marshalN__DirectiveLocation2ᚕstringᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Directive_locations(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Directive", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type __DirectiveLocation does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Directive_args(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Args, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.([]introspection.InputValue) - fc.Result = res - return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Directive_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Directive", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___InputValue_name(ctx, field) - case "description": - return ec.fieldContext___InputValue_description(ctx, field) - case "type": - return ec.fieldContext___InputValue_type(ctx, field) - case "defaultValue": - return ec.fieldContext___InputValue_defaultValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Directive_isRepeatable(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsRepeatable, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(bool) - fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Directive_isRepeatable(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Directive", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___EnumValue_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___EnumValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__EnumValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___EnumValue_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___EnumValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__EnumValue", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___EnumValue_isDeprecated(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsDeprecated(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(bool) - fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__EnumValue", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___EnumValue_deprecationReason(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.DeprecationReason(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__EnumValue", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Field_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Field_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Field", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Field_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Field_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Field", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Field_args(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Args, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.([]introspection.InputValue) - fc.Result = res - return ec.marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Field_args(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Field", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___InputValue_name(ctx, field) - case "description": - return ec.fieldContext___InputValue_description(ctx, field) - case "type": - return ec.fieldContext___InputValue_type(ctx, field) - case "defaultValue": - return ec.fieldContext___InputValue_defaultValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Field_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Type, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Field_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Field", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Field_isDeprecated(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.IsDeprecated(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(bool) - fc.Result = res - return ec.marshalNBoolean2bool(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Field_isDeprecated(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Field", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type Boolean does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Field_deprecationReason(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.DeprecationReason(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Field_deprecationReason(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Field", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___InputValue_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___InputValue_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__InputValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___InputValue_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___InputValue_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__InputValue", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___InputValue_type(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Type, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___InputValue_type(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__InputValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___InputValue_defaultValue(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.DefaultValue, nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__InputValue", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Schema_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Schema_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Schema_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Schema", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Schema_types(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Types(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.([]introspection.Type) - fc.Result = res - return ec.marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Schema_types(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Schema", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Schema_queryType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.QueryType(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Schema_queryType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Schema", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Schema_mutationType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.MutationType(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Schema_mutationType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Schema", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Schema_subscriptionType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.SubscriptionType(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Schema", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Schema_directives(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Directives(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.([]introspection.Directive) - fc.Result = res - return ec.marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Schema_directives(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Schema", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___Directive_name(ctx, field) - case "description": - return ec.fieldContext___Directive_description(ctx, field) - case "locations": - return ec.fieldContext___Directive_locations(ctx, field) - case "args": - return ec.fieldContext___Directive_args(ctx, field) - case "isRepeatable": - return ec.fieldContext___Directive_isRepeatable(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Directive", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_kind(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Kind(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } - return graphql.Null - } - res := resTmp.(string) - fc.Result = res - return ec.marshalN__TypeKind2string(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_kind(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type __TypeKind does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_name(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Name(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_name(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_description(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Description(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_fields(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Fields(fc.Args["includeDeprecated"].(bool)), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]introspection.Field) - fc.Result = res - return ec.marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_fields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___Field_name(ctx, field) - case "description": - return ec.fieldContext___Field_description(ctx, field) - case "args": - return ec.fieldContext___Field_args(ctx, field) - case "type": - return ec.fieldContext___Field_type(ctx, field) - case "isDeprecated": - return ec.fieldContext___Field_isDeprecated(ctx, field) - case "deprecationReason": - return ec.fieldContext___Field_deprecationReason(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Field", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field___Type_fields_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_interfaces(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.Interfaces(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_interfaces(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_possibleTypes(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.PossibleTypes(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_possibleTypes(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_enumValues(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.EnumValues(fc.Args["includeDeprecated"].(bool)), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]introspection.EnumValue) - fc.Result = res - return ec.marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_enumValues(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___EnumValue_name(ctx, field) - case "description": - return ec.fieldContext___EnumValue_description(ctx, field) - case "isDeprecated": - return ec.fieldContext___EnumValue_isDeprecated(ctx, field) - case "deprecationReason": - return ec.fieldContext___EnumValue_deprecationReason(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __EnumValue", field.Name) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field___Type_enumValues_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_inputFields(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.InputFields(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.([]introspection.InputValue) - fc.Result = res - return ec.marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_inputFields(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext___InputValue_name(ctx, field) - case "description": - return ec.fieldContext___InputValue_description(ctx, field) - case "type": - return ec.fieldContext___InputValue_type(ctx, field) - case "defaultValue": - return ec.fieldContext___InputValue_defaultValue(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __InputValue", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_ofType(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.OfType(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*introspection.Type) - fc.Result = res - return ec.marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_ofType(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "kind": - return ec.fieldContext___Type_kind(ctx, field) - case "name": - return ec.fieldContext___Type_name(ctx, field) - case "description": - return ec.fieldContext___Type_description(ctx, field) - case "fields": - return ec.fieldContext___Type_fields(ctx, field) - case "interfaces": - return ec.fieldContext___Type_interfaces(ctx, field) - case "possibleTypes": - return ec.fieldContext___Type_possibleTypes(ctx, field) - case "enumValues": - return ec.fieldContext___Type_enumValues(ctx, field) - case "inputFields": - return ec.fieldContext___Type_inputFields(ctx, field) - case "ofType": - return ec.fieldContext___Type_ofType(ctx, field) - case "specifiedByURL": - return ec.fieldContext___Type_specifiedByURL(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type __Type", field.Name) - }, - } - return fc, nil -} - -func (ec *executionContext) ___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) (ret graphql.Marshaler) { - fc, err := ec.fieldContext___Type_specifiedByURL(ctx, field) - if err != nil { - return graphql.Null - } - ctx = graphql.WithFieldContext(ctx, fc) - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = graphql.Null - } - }() - resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { - ctx = rctx // use context from middleware stack in children - return obj.SpecifiedByURL(), nil - }) - if err != nil { - ec.Error(ctx, err) - return graphql.Null - } - if resTmp == nil { - return graphql.Null - } - res := resTmp.(*string) - fc.Result = res - return ec.marshalOString2ᚖstring(ctx, field.Selections, res) -} - -func (ec *executionContext) fieldContext___Type_specifiedByURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "__Type", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return nil, errors.New("field of type String does not have child fields") - }, - } - return fc, nil -} - -// endregion **************************** field.gotpl ***************************** - -// region **************************** input.gotpl ***************************** - -func (ec *executionContext) unmarshalInputInstanceFilter(ctx context.Context, obj interface{}) (graph.InstanceFilter, error) { - var it graph.InstanceFilter - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v - } - - fieldsInOrder := [...]string{"ids", "typeIds", "names", "externalIds"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "ids": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) - data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Ids = data - case "typeIds": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("typeIds")) - data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.TypeIds = data - case "names": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Names = data - case "externalIds": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.ExternalIds = data - } - } - - return it, nil -} - -func (ec *executionContext) unmarshalInputTypeFilter(ctx context.Context, obj interface{}) (graph.TypeFilter, error) { - var it graph.TypeFilter - asMap := map[string]interface{}{} - for k, v := range obj.(map[string]interface{}) { - asMap[k] = v - } - - fieldsInOrder := [...]string{"ids", "names", "versions", "externalIds"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "ids": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ids")) - data, err := ec.unmarshalOID2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Ids = data - case "names": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("names")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Names = data - case "versions": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("versions")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Versions = data - case "externalIds": - var err error - - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("externalIds")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.ExternalIds = data - } - } - - return it, nil -} - -// endregion **************************** input.gotpl ***************************** - -// region ************************** interface.gotpl *************************** - -func (ec *executionContext) _ArtifactTypeInterface(ctx context.Context, sel ast.SelectionSet, obj graph.ArtifactTypeInterface) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case graph.ArtifactType: - return ec._ArtifactType(ctx, sel, &obj) - case *graph.ArtifactType: - if obj == nil { - return graphql.Null - } - return ec._ArtifactType(ctx, sel, obj) - case graph.MlmdDataset: - return ec._MlmdDataset(ctx, sel, &obj) - case *graph.MlmdDataset: - if obj == nil { - return graphql.Null - } - return ec._MlmdDataset(ctx, sel, obj) - case graph.MlmdModel: - return ec._MlmdModel(ctx, sel, &obj) - case *graph.MlmdModel: - if obj == nil { - return graphql.Null - } - return ec._MlmdModel(ctx, sel, obj) - case graph.MlmdMetrics: - return ec._MlmdMetrics(ctx, sel, &obj) - case *graph.MlmdMetrics: - if obj == nil { - return graphql.Null - } - return ec._MlmdMetrics(ctx, sel, obj) - case graph.MlmdStatistics: - return ec._MlmdStatistics(ctx, sel, &obj) - case *graph.MlmdStatistics: - if obj == nil { - return graphql.Null - } - return ec._MlmdStatistics(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - -func (ec *executionContext) _ContextTypeInterface(ctx context.Context, sel ast.SelectionSet, obj graph.ContextTypeInterface) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case graph.ContextType: - return ec._ContextType(ctx, sel, &obj) - case *graph.ContextType: - if obj == nil { - return graphql.Null - } - return ec._ContextType(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - -func (ec *executionContext) _ExecutionTypeInterface(ctx context.Context, sel ast.SelectionSet, obj graph.ExecutionTypeInterface) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case graph.ExecutionType: - return ec._ExecutionType(ctx, sel, &obj) - case *graph.ExecutionType: - if obj == nil { - return graphql.Null - } - return ec._ExecutionType(ctx, sel, obj) - case graph.MlmdTrain: - return ec._MlmdTrain(ctx, sel, &obj) - case *graph.MlmdTrain: - if obj == nil { - return graphql.Null - } - return ec._MlmdTrain(ctx, sel, obj) - case graph.MlmdTransform: - return ec._MlmdTransform(ctx, sel, &obj) - case *graph.MlmdTransform: - if obj == nil { - return graphql.Null - } - return ec._MlmdTransform(ctx, sel, obj) - case graph.MlmdProcess: - return ec._MlmdProcess(ctx, sel, &obj) - case *graph.MlmdProcess: - if obj == nil { - return graphql.Null - } - return ec._MlmdProcess(ctx, sel, obj) - case graph.MlmdEvaluate: - return ec._MlmdEvaluate(ctx, sel, &obj) - case *graph.MlmdEvaluate: - if obj == nil { - return graphql.Null - } - return ec._MlmdEvaluate(ctx, sel, obj) - case graph.MlmdDeploy: - return ec._MlmdDeploy(ctx, sel, &obj) - case *graph.MlmdDeploy: - if obj == nil { - return graphql.Null - } - return ec._MlmdDeploy(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - -func (ec *executionContext) _Type(ctx context.Context, sel ast.SelectionSet, obj graph.Type) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case graph.ArtifactTypeInterface: - if obj == nil { - return graphql.Null - } - return ec._ArtifactTypeInterface(ctx, sel, obj) - case graph.ArtifactType: - return ec._ArtifactType(ctx, sel, &obj) - case *graph.ArtifactType: - if obj == nil { - return graphql.Null - } - return ec._ArtifactType(ctx, sel, obj) - case graph.ContextTypeInterface: - if obj == nil { - return graphql.Null - } - return ec._ContextTypeInterface(ctx, sel, obj) - case graph.ContextType: - return ec._ContextType(ctx, sel, &obj) - case *graph.ContextType: - if obj == nil { - return graphql.Null - } - return ec._ContextType(ctx, sel, obj) - case graph.ExecutionTypeInterface: - if obj == nil { - return graphql.Null - } - return ec._ExecutionTypeInterface(ctx, sel, obj) - case graph.ExecutionType: - return ec._ExecutionType(ctx, sel, &obj) - case *graph.ExecutionType: - if obj == nil { - return graphql.Null - } - return ec._ExecutionType(ctx, sel, obj) - case graph.MlmdDataset: - return ec._MlmdDataset(ctx, sel, &obj) - case *graph.MlmdDataset: - if obj == nil { - return graphql.Null - } - return ec._MlmdDataset(ctx, sel, obj) - case graph.MlmdModel: - return ec._MlmdModel(ctx, sel, &obj) - case *graph.MlmdModel: - if obj == nil { - return graphql.Null - } - return ec._MlmdModel(ctx, sel, obj) - case graph.MlmdMetrics: - return ec._MlmdMetrics(ctx, sel, &obj) - case *graph.MlmdMetrics: - if obj == nil { - return graphql.Null - } - return ec._MlmdMetrics(ctx, sel, obj) - case graph.MlmdStatistics: - return ec._MlmdStatistics(ctx, sel, &obj) - case *graph.MlmdStatistics: - if obj == nil { - return graphql.Null - } - return ec._MlmdStatistics(ctx, sel, obj) - case graph.MlmdTrain: - return ec._MlmdTrain(ctx, sel, &obj) - case *graph.MlmdTrain: - if obj == nil { - return graphql.Null - } - return ec._MlmdTrain(ctx, sel, obj) - case graph.MlmdTransform: - return ec._MlmdTransform(ctx, sel, &obj) - case *graph.MlmdTransform: - if obj == nil { - return graphql.Null - } - return ec._MlmdTransform(ctx, sel, obj) - case graph.MlmdProcess: - return ec._MlmdProcess(ctx, sel, &obj) - case *graph.MlmdProcess: - if obj == nil { - return graphql.Null - } - return ec._MlmdProcess(ctx, sel, obj) - case graph.MlmdEvaluate: - return ec._MlmdEvaluate(ctx, sel, &obj) - case *graph.MlmdEvaluate: - if obj == nil { - return graphql.Null - } - return ec._MlmdEvaluate(ctx, sel, obj) - case graph.MlmdDeploy: - return ec._MlmdDeploy(ctx, sel, &obj) - case *graph.MlmdDeploy: - if obj == nil { - return graphql.Null - } - return ec._MlmdDeploy(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - -func (ec *executionContext) _Value(ctx context.Context, sel ast.SelectionSet, obj graph.Value) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case graph.IntValue: - return ec._IntValue(ctx, sel, &obj) - case *graph.IntValue: - if obj == nil { - return graphql.Null - } - return ec._IntValue(ctx, sel, obj) - case graph.DoubleValue: - return ec._DoubleValue(ctx, sel, &obj) - case *graph.DoubleValue: - if obj == nil { - return graphql.Null - } - return ec._DoubleValue(ctx, sel, obj) - case graph.StringValue: - return ec._StringValue(ctx, sel, &obj) - case *graph.StringValue: - if obj == nil { - return graphql.Null - } - return ec._StringValue(ctx, sel, obj) - case graph.BoolValue: - return ec._BoolValue(ctx, sel, &obj) - case *graph.BoolValue: - if obj == nil { - return graphql.Null - } - return ec._BoolValue(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - -// endregion ************************** interface.gotpl *************************** - -// region **************************** object.gotpl **************************** - -var artifactImplementors = []string{"Artifact"} - -func (ec *executionContext) _Artifact(ctx context.Context, sel ast.SelectionSet, obj *graph.Artifact) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, artifactImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("Artifact") - case "id": - out.Values[i] = ec._Artifact_id(ctx, field, obj) - case "typeId": - out.Values[i] = ec._Artifact_typeId(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "uri": - out.Values[i] = ec._Artifact_uri(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "state": - out.Values[i] = ec._Artifact_state(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "name": - out.Values[i] = ec._Artifact_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "externalId": - out.Values[i] = ec._Artifact_externalId(ctx, field, obj) - case "createTimeSinceEpoch": - out.Values[i] = ec._Artifact_createTimeSinceEpoch(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "lastUpdateTimeSinceEpoch": - out.Values[i] = ec._Artifact_lastUpdateTimeSinceEpoch(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "type": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Artifact_type(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } - - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) - - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "properties": - out.Values[i] = ec._Artifact_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var artifactPropertyImplementors = []string{"ArtifactProperty"} - -func (ec *executionContext) _ArtifactProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactProperty) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, artifactPropertyImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("ArtifactProperty") - case "artifactId": - out.Values[i] = ec._ArtifactProperty_artifactId(ctx, field, obj) - case "name": - out.Values[i] = ec._ArtifactProperty_name(ctx, field, obj) - case "isCustomProperty": - out.Values[i] = ec._ArtifactProperty_isCustomProperty(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "propertyValue": - out.Values[i] = ec._ArtifactProperty_propertyValue(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var artifactTypeImplementors = []string{"ArtifactType", "ArtifactTypeInterface", "Type"} - -func (ec *executionContext) _ArtifactType(ctx context.Context, sel ast.SelectionSet, obj *graph.ArtifactType) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, artifactTypeImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("ArtifactType") - case "id": - out.Values[i] = ec._ArtifactType_id(ctx, field, obj) - case "name": - out.Values[i] = ec._ArtifactType_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._ArtifactType_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._ArtifactType_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._ArtifactType_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._ArtifactType_externalId(ctx, field, obj) - case "properties": - out.Values[i] = ec._ArtifactType_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var boolValueImplementors = []string{"BoolValue", "Value"} - -func (ec *executionContext) _BoolValue(ctx context.Context, sel ast.SelectionSet, obj *graph.BoolValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, boolValueImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("BoolValue") - case "value": - out.Values[i] = ec._BoolValue_value(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var contextImplementors = []string{"Context"} - -func (ec *executionContext) _Context(ctx context.Context, sel ast.SelectionSet, obj *graph.Context) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, contextImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("Context") - case "id": - out.Values[i] = ec._Context_id(ctx, field, obj) - case "typeId": - out.Values[i] = ec._Context_typeId(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "name": - out.Values[i] = ec._Context_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._Context_externalId(ctx, field, obj) - case "createTimeSinceEpoch": - out.Values[i] = ec._Context_createTimeSinceEpoch(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "lastUpdateTimeSinceEpoch": - out.Values[i] = ec._Context_lastUpdateTimeSinceEpoch(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "type": - out.Values[i] = ec._Context_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "parent": - out.Values[i] = ec._Context_parent(ctx, field, obj) - case "children": - out.Values[i] = ec._Context_children(ctx, field, obj) - case "attributions": - out.Values[i] = ec._Context_attributions(ctx, field, obj) - case "associations": - out.Values[i] = ec._Context_associations(ctx, field, obj) - case "properties": - out.Values[i] = ec._Context_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var contextPropertyImplementors = []string{"ContextProperty"} - -func (ec *executionContext) _ContextProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextProperty) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, contextPropertyImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("ContextProperty") - case "contextId": - out.Values[i] = ec._ContextProperty_contextId(ctx, field, obj) - case "name": - out.Values[i] = ec._ContextProperty_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "isCustomProperty": - out.Values[i] = ec._ContextProperty_isCustomProperty(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "propertyValue": - out.Values[i] = ec._ContextProperty_propertyValue(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var contextTypeImplementors = []string{"ContextType", "ContextTypeInterface", "Type"} - -func (ec *executionContext) _ContextType(ctx context.Context, sel ast.SelectionSet, obj *graph.ContextType) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, contextTypeImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("ContextType") - case "id": - out.Values[i] = ec._ContextType_id(ctx, field, obj) - case "name": - out.Values[i] = ec._ContextType_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._ContextType_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._ContextType_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._ContextType_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._ContextType_externalId(ctx, field, obj) - case "properties": - out.Values[i] = ec._ContextType_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var doubleValueImplementors = []string{"DoubleValue", "Value"} - -func (ec *executionContext) _DoubleValue(ctx context.Context, sel ast.SelectionSet, obj *graph.DoubleValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, doubleValueImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("DoubleValue") - case "value": - out.Values[i] = ec._DoubleValue_value(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var eventImplementors = []string{"Event"} - -func (ec *executionContext) _Event(ctx context.Context, sel ast.SelectionSet, obj *graph.Event) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, eventImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("Event") - case "id": - out.Values[i] = ec._Event_id(ctx, field, obj) - case "artifactId": - out.Values[i] = ec._Event_artifactId(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "executionId": - out.Values[i] = ec._Event_executionId(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "type": - out.Values[i] = ec._Event_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "artifact": - out.Values[i] = ec._Event_artifact(ctx, field, obj) - case "execution": - out.Values[i] = ec._Event_execution(ctx, field, obj) - case "millisecondsSinceEpoch": - out.Values[i] = ec._Event_millisecondsSinceEpoch(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var eventPathImplementors = []string{"EventPath"} - -func (ec *executionContext) _EventPath(ctx context.Context, sel ast.SelectionSet, obj *graph.EventPath) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, eventPathImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("EventPath") - case "eventId": - out.Values[i] = ec._EventPath_eventId(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "isIndexStep": - out.Values[i] = ec._EventPath_isIndexStep(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "stepIndex": - out.Values[i] = ec._EventPath_stepIndex(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "stepKey": - out.Values[i] = ec._EventPath_stepKey(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var executionImplementors = []string{"Execution"} - -func (ec *executionContext) _Execution(ctx context.Context, sel ast.SelectionSet, obj *graph.Execution) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, executionImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("Execution") - case "id": - out.Values[i] = ec._Execution_id(ctx, field, obj) - case "typeId": - out.Values[i] = ec._Execution_typeId(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "lastKnownState": - out.Values[i] = ec._Execution_lastKnownState(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "name": - out.Values[i] = ec._Execution_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._Execution_externalId(ctx, field, obj) - case "createTimeSinceEpoch": - out.Values[i] = ec._Execution_createTimeSinceEpoch(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "lastUpdateTimeSinceEpoch": - out.Values[i] = ec._Execution_lastUpdateTimeSinceEpoch(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "type": - out.Values[i] = ec._Execution_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "properties": - out.Values[i] = ec._Execution_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var executionPropertyImplementors = []string{"ExecutionProperty"} - -func (ec *executionContext) _ExecutionProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionProperty) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, executionPropertyImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("ExecutionProperty") - case "executionId": - out.Values[i] = ec._ExecutionProperty_executionId(ctx, field, obj) - case "name": - out.Values[i] = ec._ExecutionProperty_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "isCustomProperty": - out.Values[i] = ec._ExecutionProperty_isCustomProperty(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "propertyValue": - out.Values[i] = ec._ExecutionProperty_propertyValue(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var executionTypeImplementors = []string{"ExecutionType", "ExecutionTypeInterface", "Type"} - -func (ec *executionContext) _ExecutionType(ctx context.Context, sel ast.SelectionSet, obj *graph.ExecutionType) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, executionTypeImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("ExecutionType") - case "id": - out.Values[i] = ec._ExecutionType_id(ctx, field, obj) - case "name": - out.Values[i] = ec._ExecutionType_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._ExecutionType_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._ExecutionType_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._ExecutionType_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._ExecutionType_externalId(ctx, field, obj) - case "inputType": - out.Values[i] = ec._ExecutionType_inputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "outputType": - out.Values[i] = ec._ExecutionType_outputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "properties": - out.Values[i] = ec._ExecutionType_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var intValueImplementors = []string{"IntValue", "Value"} - -func (ec *executionContext) _IntValue(ctx context.Context, sel ast.SelectionSet, obj *graph.IntValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, intValueImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("IntValue") - case "value": - out.Values[i] = ec._IntValue_value(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdDatasetImplementors = []string{"MlmdDataset", "ArtifactTypeInterface", "Type"} - -func (ec *executionContext) _MlmdDataset(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdDataset) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdDatasetImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdDataset") - case "id": - out.Values[i] = ec._MlmdDataset_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdDataset_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdDataset_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdDataset_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdDataset_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdDataset_externalId(ctx, field, obj) - case "properties": - out.Values[i] = ec._MlmdDataset_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdDeployImplementors = []string{"MlmdDeploy", "ExecutionTypeInterface", "Type"} - -func (ec *executionContext) _MlmdDeploy(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdDeploy) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdDeployImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdDeploy") - case "id": - out.Values[i] = ec._MlmdDeploy_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdDeploy_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdDeploy_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdDeploy_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdDeploy_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdDeploy_externalId(ctx, field, obj) - case "inputType": - out.Values[i] = ec._MlmdDeploy_inputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "outputType": - out.Values[i] = ec._MlmdDeploy_outputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "properties": - out.Values[i] = ec._MlmdDeploy_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdEvaluateImplementors = []string{"MlmdEvaluate", "ExecutionTypeInterface", "Type"} - -func (ec *executionContext) _MlmdEvaluate(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdEvaluate) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdEvaluateImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdEvaluate") - case "id": - out.Values[i] = ec._MlmdEvaluate_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdEvaluate_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdEvaluate_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdEvaluate_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdEvaluate_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdEvaluate_externalId(ctx, field, obj) - case "inputType": - out.Values[i] = ec._MlmdEvaluate_inputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "outputType": - out.Values[i] = ec._MlmdEvaluate_outputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "properties": - out.Values[i] = ec._MlmdEvaluate_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdMetricsImplementors = []string{"MlmdMetrics", "ArtifactTypeInterface", "Type"} - -func (ec *executionContext) _MlmdMetrics(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdMetrics) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdMetricsImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdMetrics") - case "id": - out.Values[i] = ec._MlmdMetrics_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdMetrics_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdMetrics_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdMetrics_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdMetrics_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdMetrics_externalId(ctx, field, obj) - case "properties": - out.Values[i] = ec._MlmdMetrics_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdModelImplementors = []string{"MlmdModel", "ArtifactTypeInterface", "Type"} - -func (ec *executionContext) _MlmdModel(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdModel) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdModelImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdModel") - case "id": - out.Values[i] = ec._MlmdModel_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdModel_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdModel_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdModel_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdModel_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdModel_externalId(ctx, field, obj) - case "properties": - out.Values[i] = ec._MlmdModel_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdProcessImplementors = []string{"MlmdProcess", "ExecutionTypeInterface", "Type"} - -func (ec *executionContext) _MlmdProcess(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdProcess) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdProcessImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdProcess") - case "id": - out.Values[i] = ec._MlmdProcess_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdProcess_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdProcess_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdProcess_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdProcess_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdProcess_externalId(ctx, field, obj) - case "inputType": - out.Values[i] = ec._MlmdProcess_inputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "outputType": - out.Values[i] = ec._MlmdProcess_outputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "properties": - out.Values[i] = ec._MlmdProcess_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdStatisticsImplementors = []string{"MlmdStatistics", "ArtifactTypeInterface", "Type"} - -func (ec *executionContext) _MlmdStatistics(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdStatistics) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdStatisticsImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdStatistics") - case "id": - out.Values[i] = ec._MlmdStatistics_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdStatistics_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdStatistics_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdStatistics_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdStatistics_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdStatistics_externalId(ctx, field, obj) - case "properties": - out.Values[i] = ec._MlmdStatistics_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdTrainImplementors = []string{"MlmdTrain", "ExecutionTypeInterface", "Type"} - -func (ec *executionContext) _MlmdTrain(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdTrain) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdTrainImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdTrain") - case "id": - out.Values[i] = ec._MlmdTrain_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdTrain_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdTrain_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdTrain_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdTrain_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdTrain_externalId(ctx, field, obj) - case "inputType": - out.Values[i] = ec._MlmdTrain_inputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "outputType": - out.Values[i] = ec._MlmdTrain_outputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "properties": - out.Values[i] = ec._MlmdTrain_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var mlmdTransformImplementors = []string{"MlmdTransform", "ExecutionTypeInterface", "Type"} - -func (ec *executionContext) _MlmdTransform(ctx context.Context, sel ast.SelectionSet, obj *graph.MlmdTransform) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, mlmdTransformImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("MlmdTransform") - case "id": - out.Values[i] = ec._MlmdTransform_id(ctx, field, obj) - case "name": - out.Values[i] = ec._MlmdTransform_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "version": - out.Values[i] = ec._MlmdTransform_version(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "typeKind": - out.Values[i] = ec._MlmdTransform_typeKind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec._MlmdTransform_description(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "externalId": - out.Values[i] = ec._MlmdTransform_externalId(ctx, field, obj) - case "inputType": - out.Values[i] = ec._MlmdTransform_inputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "outputType": - out.Values[i] = ec._MlmdTransform_outputType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "properties": - out.Values[i] = ec._MlmdTransform_properties(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var queryImplementors = []string{"Query"} - -func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, queryImplementors) - ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{ - Object: "Query", - }) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - innerCtx := graphql.WithRootFieldContext(ctx, &graphql.RootFieldContext{ - Object: field.Name, - Field: field, - }) - - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("Query") - case "types": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_types(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "artifactTypes": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_artifactTypes(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "contextTypes": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_contextTypes(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "executionTypes": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_executionTypes(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "artifacts": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_artifacts(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "contexts": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_contexts(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "executions": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_executions(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "events": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_events(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "mlmdDataset": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_mlmdDataset(ctx, field) - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "__type": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Query___type(ctx, field) - }) - case "__schema": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Query___schema(ctx, field) - }) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var stringValueImplementors = []string{"StringValue", "Value"} - -func (ec *executionContext) _StringValue(ctx context.Context, sel ast.SelectionSet, obj *graph.StringValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, stringValueImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("StringValue") - case "value": - out.Values[i] = ec._StringValue_value(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var typePropertyImplementors = []string{"TypeProperty"} - -func (ec *executionContext) _TypeProperty(ctx context.Context, sel ast.SelectionSet, obj *graph.TypeProperty) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, typePropertyImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("TypeProperty") - case "typeId": - out.Values[i] = ec._TypeProperty_typeId(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "name": - out.Values[i] = ec._TypeProperty_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "dataType": - out.Values[i] = ec._TypeProperty_dataType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var __DirectiveImplementors = []string{"__Directive"} - -func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, __DirectiveImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("__Directive") - case "name": - out.Values[i] = ec.___Directive_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec.___Directive_description(ctx, field, obj) - case "locations": - out.Values[i] = ec.___Directive_locations(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "args": - out.Values[i] = ec.___Directive_args(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "isRepeatable": - out.Values[i] = ec.___Directive_isRepeatable(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var __EnumValueImplementors = []string{"__EnumValue"} - -func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, __EnumValueImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("__EnumValue") - case "name": - out.Values[i] = ec.___EnumValue_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec.___EnumValue_description(ctx, field, obj) - case "isDeprecated": - out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "deprecationReason": - out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var __FieldImplementors = []string{"__Field"} - -func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, __FieldImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("__Field") - case "name": - out.Values[i] = ec.___Field_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec.___Field_description(ctx, field, obj) - case "args": - out.Values[i] = ec.___Field_args(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "type": - out.Values[i] = ec.___Field_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "isDeprecated": - out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "deprecationReason": - out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var __InputValueImplementors = []string{"__InputValue"} - -func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, __InputValueImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("__InputValue") - case "name": - out.Values[i] = ec.___InputValue_name(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "description": - out.Values[i] = ec.___InputValue_description(ctx, field, obj) - case "type": - out.Values[i] = ec.___InputValue_type(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "defaultValue": - out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var __SchemaImplementors = []string{"__Schema"} - -func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, __SchemaImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("__Schema") - case "description": - out.Values[i] = ec.___Schema_description(ctx, field, obj) - case "types": - out.Values[i] = ec.___Schema_types(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "queryType": - out.Values[i] = ec.___Schema_queryType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "mutationType": - out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) - case "subscriptionType": - out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) - case "directives": - out.Values[i] = ec.___Schema_directives(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var __TypeImplementors = []string{"__Type"} - -func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, __TypeImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("__Type") - case "kind": - out.Values[i] = ec.___Type_kind(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "name": - out.Values[i] = ec.___Type_name(ctx, field, obj) - case "description": - out.Values[i] = ec.___Type_description(ctx, field, obj) - case "fields": - out.Values[i] = ec.___Type_fields(ctx, field, obj) - case "interfaces": - out.Values[i] = ec.___Type_interfaces(ctx, field, obj) - case "possibleTypes": - out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) - case "enumValues": - out.Values[i] = ec.___Type_enumValues(ctx, field, obj) - case "inputFields": - out.Values[i] = ec.___Type_inputFields(ctx, field, obj) - case "ofType": - out.Values[i] = ec.___Type_ofType(ctx, field, obj) - case "specifiedByURL": - out.Values[i] = ec.___Type_specifiedByURL(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.deferred, int32(len(deferred))) - - for label, dfs := range deferred { - ec.processDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -// endregion **************************** object.gotpl **************************** - -// region ***************************** type.gotpl ***************************** - -func (ec *executionContext) marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._Artifact(ctx, sel, v) -} - -func (ec *executionContext) marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactProperty) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._ArtifactProperty(ctx, sel, v) -} - -func (ec *executionContext) marshalNArtifactType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v graph.ArtifactType) graphql.Marshaler { - return ec._ArtifactType(ctx, sel, &v) -} - -func (ec *executionContext) marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx context.Context, sel ast.SelectionSet, v *graph.ArtifactType) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._ArtifactType(ctx, sel, v) -} - -func (ec *executionContext) unmarshalNBoolean2bool(ctx context.Context, v interface{}) (bool, error) { - res, err := graphql.UnmarshalBoolean(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - res := graphql.MarshalBoolean(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return res -} - -func (ec *executionContext) marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._Context(ctx, sel, v) -} - -func (ec *executionContext) marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ContextProperty) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._ContextProperty(ctx, sel, v) -} - -func (ec *executionContext) marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextType(ctx context.Context, sel ast.SelectionSet, v *graph.ContextType) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._ContextType(ctx, sel, v) -} - -func (ec *executionContext) marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEvent(ctx context.Context, sel ast.SelectionSet, v *graph.Event) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._Event(ctx, sel, v) -} - -func (ec *executionContext) marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._Execution(ctx, sel, v) -} - -func (ec *executionContext) marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionProperty(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionProperty) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._ExecutionProperty(ctx, sel, v) -} - -func (ec *executionContext) marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionType(ctx context.Context, sel ast.SelectionSet, v *graph.ExecutionType) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._ExecutionType(ctx, sel, v) -} - -func (ec *executionContext) unmarshalNFloat2float64(ctx context.Context, v interface{}) (float64, error) { - res, err := graphql.UnmarshalFloatContext(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNFloat2float64(ctx context.Context, sel ast.SelectionSet, v float64) graphql.Marshaler { - res := graphql.MarshalFloatContext(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return graphql.WrapContextMarshaler(ctx, res) -} - -func (ec *executionContext) unmarshalNID2string(ctx context.Context, v interface{}) (string, error) { - res, err := graphql.UnmarshalID(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNID2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - res := graphql.MarshalID(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return res -} - -func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) { - res, err := graphql.UnmarshalInt(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { - res := graphql.MarshalInt(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return res -} - -func (ec *executionContext) marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDataset(ctx context.Context, sel ast.SelectionSet, v *graph.MlmdDataset) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._MlmdDataset(ctx, sel, v) -} - -func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) { - res, err := graphql.UnmarshalString(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - res := graphql.MarshalString(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return res -} - -func (ec *executionContext) marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐType(ctx context.Context, sel ast.SelectionSet, v graph.Type) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._Type(ctx, sel, v) -} - -func (ec *executionContext) marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeProperty(ctx context.Context, sel ast.SelectionSet, v *graph.TypeProperty) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._TypeProperty(ctx, sel, v) -} - -func (ec *executionContext) marshalNValue2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐValue(ctx context.Context, sel ast.SelectionSet, v graph.Value) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._Value(ctx, sel, v) -} - -func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { - return ec.___Directive(ctx, sel, &v) -} - -func (ec *executionContext) marshalN__Directive2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirectiveᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Directive) graphql.Marshaler { - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) unmarshalN__DirectiveLocation2string(ctx context.Context, v interface{}) (string, error) { - res, err := graphql.UnmarshalString(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalN__DirectiveLocation2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - res := graphql.MarshalString(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return res -} - -func (ec *executionContext) unmarshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]string, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalN__DirectiveLocation2string(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil -} - -func (ec *executionContext) marshalN__DirectiveLocation2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__DirectiveLocation2string(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx context.Context, sel ast.SelectionSet, v introspection.EnumValue) graphql.Marshaler { - return ec.___EnumValue(ctx, sel, &v) -} - -func (ec *executionContext) marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx context.Context, sel ast.SelectionSet, v introspection.Field) graphql.Marshaler { - return ec.___Field(ctx, sel, &v) -} - -func (ec *executionContext) marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx context.Context, sel ast.SelectionSet, v introspection.InputValue) graphql.Marshaler { - return ec.___InputValue(ctx, sel, &v) -} - -func (ec *executionContext) marshalN__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v introspection.Type) graphql.Marshaler { - return ec.___Type(ctx, sel, &v) -} - -func (ec *executionContext) marshalN__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalN__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec.___Type(ctx, sel, v) -} - -func (ec *executionContext) unmarshalN__TypeKind2string(ctx context.Context, v interface{}) (string, error) { - res, err := graphql.UnmarshalString(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalN__TypeKind2string(ctx context.Context, sel ast.SelectionSet, v string) graphql.Marshaler { - res := graphql.MarshalString(v) - if res == graphql.Null { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - ec.Errorf(ctx, "the requested element is null which the schema does not allow") - } - } - return res -} - -func (ec *executionContext) marshalOArtifact2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Artifact) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOArtifact2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifact(ctx context.Context, sel ast.SelectionSet, v *graph.Artifact) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._Artifact(ctx, sel, v) -} - -func (ec *executionContext) marshalOArtifactProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactProperty) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNArtifactProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactProperty(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOArtifactType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ArtifactType) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNArtifactType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐArtifactType(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) unmarshalOBoolean2bool(ctx context.Context, v interface{}) (bool, error) { - res, err := graphql.UnmarshalBoolean(v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOBoolean2bool(ctx context.Context, sel ast.SelectionSet, v bool) graphql.Marshaler { - res := graphql.MarshalBoolean(v) - return res -} - -func (ec *executionContext) unmarshalOBoolean2ᚖbool(ctx context.Context, v interface{}) (*bool, error) { - if v == nil { - return nil, nil - } - res, err := graphql.UnmarshalBoolean(v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast.SelectionSet, v *bool) graphql.Marshaler { - if v == nil { - return graphql.Null - } - res := graphql.MarshalBoolean(*v) - return res -} - -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - return ret -} - -func (ec *executionContext) marshalOContext2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Context) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOContext2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContext(ctx context.Context, sel ast.SelectionSet, v *graph.Context) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._Context(ctx, sel, v) -} - -func (ec *executionContext) marshalOContextProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextProperty) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNContextProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextProperty(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOContextType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ContextType) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNContextType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐContextType(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOEvent2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEventᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Event) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNEvent2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐEvent(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOExecution2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.Execution) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOExecution2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecution(ctx context.Context, sel ast.SelectionSet, v *graph.Execution) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._Execution(ctx, sel, v) -} - -func (ec *executionContext) marshalOExecutionProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionPropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionProperty) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNExecutionProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionProperty(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalOExecutionType2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.ExecutionType) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNExecutionType2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐExecutionType(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) unmarshalOID2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { - if v == nil { - return nil, nil - } - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]string, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNID2string(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil -} - -func (ec *executionContext) marshalOID2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - for i := range v { - ret[i] = ec.marshalNID2string(ctx, sel, v[i]) - } - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) unmarshalOID2ᚖstring(ctx context.Context, v interface{}) (*string, error) { - if v == nil { - return nil, nil - } - res, err := graphql.UnmarshalID(v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOID2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { - if v == nil { - return graphql.Null - } - res := graphql.MarshalID(*v) - return res -} - -func (ec *executionContext) unmarshalOInstanceFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐInstanceFilter(ctx context.Context, v interface{}) (*graph.InstanceFilter, error) { - if v == nil { - return nil, nil - } - res, err := ec.unmarshalInputInstanceFilter(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOMlmdDataset2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDatasetᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.MlmdDataset) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNMlmdDataset2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐMlmdDataset(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) unmarshalOString2ᚕstringᚄ(ctx context.Context, v interface{}) ([]string, error) { - if v == nil { - return nil, nil - } - var vSlice []interface{} - if v != nil { - vSlice = graphql.CoerceList(v) - } - var err error - res := make([]string, len(vSlice)) - for i := range vSlice { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNString2string(ctx, vSlice[i]) - if err != nil { - return nil, err - } - } - return res, nil -} - -func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel ast.SelectionSet, v []string) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - for i := range v { - ret[i] = ec.marshalNString2string(ctx, sel, v[i]) - } - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) { - if v == nil { - return nil, nil - } - res, err := graphql.UnmarshalString(v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOString2ᚖstring(ctx context.Context, sel ast.SelectionSet, v *string) graphql.Marshaler { - if v == nil { - return graphql.Null - } - res := graphql.MarshalString(*v) - return res -} - -func (ec *executionContext) marshalOType2ᚕgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []graph.Type) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNType2githubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐType(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) unmarshalOTypeFilter2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeFilter(ctx context.Context, v interface{}) (*graph.TypeFilter, error) { - if v == nil { - return nil, nil - } - res, err := ec.unmarshalInputTypeFilter(ctx, v) - return &res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalOTypeProperty2ᚕᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypePropertyᚄ(ctx context.Context, sel ast.SelectionSet, v []*graph.TypeProperty) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalNTypeProperty2ᚖgithubᚗcomᚋopendatahubᚑioᚋmodelᚑregistryᚋinternalᚋmodelᚋgraphᚐTypeProperty(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalO__EnumValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.EnumValue) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__EnumValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐEnumValue(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalO__Field2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐFieldᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Field) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__Field2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐField(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalO__InputValue2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValueᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.InputValue) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__InputValue2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐInputValue(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx context.Context, sel ast.SelectionSet, v *introspection.Schema) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec.___Schema(ctx, sel, v) -} - -func (ec *executionContext) marshalO__Type2ᚕgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐTypeᚄ(ctx context.Context, sel ast.SelectionSet, v []introspection.Type) graphql.Marshaler { - if v == nil { - return graphql.Null - } - ret := make(graphql.Array, len(v)) - var wg sync.WaitGroup - isLen1 := len(v) == 1 - if !isLen1 { - wg.Add(len(v)) - } - for i := range v { - i := i - fc := &graphql.FieldContext{ - Index: &i, - Result: &v[i], - } - ctx := graphql.WithFieldContext(ctx, fc) - f := func(i int) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - ret = nil - } - }() - if !isLen1 { - defer wg.Done() - } - ret[i] = ec.marshalN__Type2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx, sel, v[i]) - } - if isLen1 { - f(i) - } else { - go f(i) - } - - } - wg.Wait() - - for _, e := range ret { - if e == graphql.Null { - return graphql.Null - } - } - - return ret -} - -func (ec *executionContext) marshalO__Type2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐType(ctx context.Context, sel ast.SelectionSet, v *introspection.Type) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec.___Type(ctx, sel, v) -} - -// endregion ***************************** type.gotpl ***************************** diff --git a/internal/server/graph/resolver.go b/internal/server/graph/resolver.go deleted file mode 100644 index a25c09c6..00000000 --- a/internal/server/graph/resolver.go +++ /dev/null @@ -1,7 +0,0 @@ -package graph - -// This file will not be regenerated automatically. -// -// It serves as dependency injection for your app, add any dependencies you require here. - -type Resolver struct{} diff --git a/internal/server/graph/schema.resolvers.go b/internal/server/graph/schema.resolvers.go deleted file mode 100644 index f4b6d0bc..00000000 --- a/internal/server/graph/schema.resolvers.go +++ /dev/null @@ -1,65 +0,0 @@ -package graph - -// This file will be automatically regenerated based on the schema, any resolver implementations -// will be copied through when generating and any unknown code will be moved to the end. -// Code generated by github.com/99designs/gqlgen version v0.17.36 - -import ( - "context" - "fmt" - - "github.com/opendatahub-io/model-registry/internal/model/graph" -) - -// Types is the resolver for the types field. -func (r *queryResolver) Types(ctx context.Context, filter *graph.TypeFilter) ([]graph.Type, error) { - //panic(fmt.Errorf("not implemented: Types - types")) - id := "1" - return []graph.Type{graph.ArtifactType{ID: &id, Name: "TestType"}}, nil -} - -// ArtifactTypes is the resolver for the artifactTypes field. -func (r *queryResolver) ArtifactTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ArtifactType, error) { - panic(fmt.Errorf("not implemented: ArtifactTypes - artifactTypes")) -} - -// ContextTypes is the resolver for the contextTypes field. -func (r *queryResolver) ContextTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ContextType, error) { - panic(fmt.Errorf("not implemented: ContextTypes - contextTypes")) -} - -// ExecutionTypes is the resolver for the executionTypes field. -func (r *queryResolver) ExecutionTypes(ctx context.Context, filter *graph.TypeFilter) ([]*graph.ExecutionType, error) { - panic(fmt.Errorf("not implemented: ExecutionTypes - executionTypes")) -} - -// Artifacts is the resolver for the artifacts field. -func (r *queryResolver) Artifacts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Artifact, error) { - id := "1" - return []*graph.Artifact{{ID: &id, Name: "TestArtifact", TypeID: id}}, nil -} - -// Contexts is the resolver for the contexts field. -func (r *queryResolver) Contexts(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Context, error) { - panic(fmt.Errorf("not implemented: Contexts - contexts")) -} - -// Executions is the resolver for the executions field. -func (r *queryResolver) Executions(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.Execution, error) { - panic(fmt.Errorf("not implemented: Executions - executions")) -} - -// Events is the resolver for the events field. -func (r *queryResolver) Events(ctx context.Context) ([]*graph.Event, error) { - panic(fmt.Errorf("not implemented: Events - events")) -} - -// MlmdDataset is the resolver for the mlmdDataset field. -func (r *queryResolver) MlmdDataset(ctx context.Context, filter *graph.InstanceFilter) ([]*graph.MlmdDataset, error) { - panic(fmt.Errorf("not implemented: MlmdDataset - mlmdDataset")) -} - -// Query returns QueryResolver implementation. -func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } - -type queryResolver struct{ *Resolver } diff --git a/internal/server/grpc/grpc_server.go b/internal/server/grpc/grpc_server.go deleted file mode 100644 index fbdf1db9..00000000 --- a/internal/server/grpc/grpc_server.go +++ /dev/null @@ -1,591 +0,0 @@ -package grpc - -import ( - "context" - "fmt" - - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/internal/model/db" - "github.com/opendatahub-io/model-registry/internal/service" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "gorm.io/gorm" -) - -type grpcServer struct { - proto.UnimplementedMetadataStoreServiceServer - dbConnection *gorm.DB -} - -var _ proto.MetadataStoreServiceServer = grpcServer{} -var _ proto.MetadataStoreServiceServer = (*grpcServer)(nil) - -func NewGrpcServer(dbConnection *gorm.DB) proto.MetadataStoreServiceServer { - return &grpcServer{dbConnection: dbConnection} -} - -var REQUIRED_TYPE_FIELDS = []string{"name"} - -func (g grpcServer) PutArtifactType(ctx context.Context, request *proto.PutArtifactTypeRequest) (resp *proto.PutArtifactTypeResponse, err error) { - ctx, _ = service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - artifactType := request.GetArtifactType() - properties := request.ArtifactType.Properties - err = requiredFields(REQUIRED_TYPE_FIELDS, artifactType.Name) - if err != nil { - return nil, err - } - value := &db.Type{ - Name: *artifactType.Name, - Version: artifactType.Version, - TypeKind: int8(db.ARTIFACT_TYPE), - Description: artifactType.Description, - ExternalID: artifactType.ExternalId, - } - err = g.createOrUpdateType(ctx, value, properties) - if err != nil { - return nil, err - } - var typeId = int64(value.ID) - return &proto.PutArtifactTypeResponse{ - TypeId: &typeId, - }, nil -} - -func (g grpcServer) createOrUpdateType(ctx context.Context, value *db.Type, - properties map[string]proto.PropertyType) error { - // TODO handle CanAdd, CanOmit properties from type request - dbConn, _ := service.FromContext(ctx) - - if err := dbConn.Where("name = ?", value.Name).Assign(value).FirstOrCreate(value).Error; err != nil { - err = fmt.Errorf("error creating type %s: %v", value.Name, err) - return err - } - err := g.createTypeProperties(ctx, properties, value.ID) - if err != nil { - return err - } - return nil -} - -func (g grpcServer) PutExecutionType(ctx context.Context, request *proto.PutExecutionTypeRequest) (resp *proto.PutExecutionTypeResponse, err error) { - ctx, _ = service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - executionType := request.GetExecutionType() - err = requiredFields(REQUIRED_TYPE_FIELDS, executionType.Name) - if err != nil { - return nil, err - } - value := &db.Type{ - Name: *executionType.Name, - Version: executionType.Version, - TypeKind: int8(db.EXECUTION_TYPE), - Description: executionType.Description, - ExternalID: executionType.ExternalId, - } - err = g.createOrUpdateType(ctx, value, executionType.Properties) - if err != nil { - return nil, err - } - var typeId = int64(value.ID) - return &proto.PutExecutionTypeResponse{ - TypeId: &typeId, - }, nil -} - -func (g grpcServer) PutContextType(ctx context.Context, request *proto.PutContextTypeRequest) (resp *proto.PutContextTypeResponse, err error) { - ctx, _ = service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - contextType := request.GetContextType() - err = requiredFields(REQUIRED_TYPE_FIELDS, contextType.Name) - if err != nil { - return nil, err - } - value := &db.Type{ - Name: *contextType.Name, - Version: contextType.Version, - TypeKind: int8(db.CONTEXT_TYPE), - Description: contextType.Description, - ExternalID: contextType.ExternalId, - } - err = g.createOrUpdateType(ctx, value, contextType.Properties) - if err != nil { - return nil, err - } - var typeId = int64(value.ID) - return &proto.PutContextTypeResponse{ - TypeId: &typeId, - }, nil -} - -func (g grpcServer) PutTypes(ctx context.Context, request *proto.PutTypesRequest) (resp *proto.PutTypesResponse, err error) { - ctx, _ = service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - response := &proto.PutTypesResponse{} - - for _, ar := range request.ArtifactTypes { - var at *proto.PutArtifactTypeResponse - at, err = g.PutArtifactType(ctx, &proto.PutArtifactTypeRequest{ - ArtifactType: ar, - CanAddFields: request.CanAddFields, - CanOmitFields: request.CanOmitFields, - TransactionOptions: request.TransactionOptions, - }) - if err != nil { - return response, err - } - response.ArtifactTypeIds = append(response.ArtifactTypeIds, *at.TypeId) - } - for _, ex := range request.ExecutionTypes { - var er *proto.PutExecutionTypeResponse - er, err = g.PutExecutionType(ctx, &proto.PutExecutionTypeRequest{ - ExecutionType: ex, - CanAddFields: request.CanAddFields, - CanOmitFields: request.CanOmitFields, - TransactionOptions: request.TransactionOptions, - }) - if err != nil { - return response, err - } - response.ExecutionTypeIds = append(response.ExecutionTypeIds, *er.TypeId) - } - for _, ct := range request.ContextTypes { - var cr *proto.PutContextTypeResponse - cr, err = g.PutContextType(ctx, &proto.PutContextTypeRequest{ - ContextType: ct, - CanAddFields: request.CanAddFields, - CanOmitFields: request.CanOmitFields, - TransactionOptions: request.TransactionOptions, - }) - if err != nil { - return response, err - } - response.ContextTypeIds = append(response.ContextTypeIds, *cr.TypeId) - } - return response, nil -} - -var REQUIRED_ARTIFACT_FIELDS = []string{"type_id", "uri"} - -func (g grpcServer) PutArtifacts(ctx context.Context, request *proto.PutArtifactsRequest) (resp *proto.PutArtifactsResponse, err error) { - ctx, dbConn := service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - var artifactIds []int64 - for _, artifact := range request.Artifacts { - err = requiredFields(REQUIRED_ARTIFACT_FIELDS, artifact.TypeId, artifact.Uri) - if err != nil { - return nil, err - } - value := &db.Artifact{ - TypeID: *artifact.TypeId, - URI: artifact.Uri, - Name: artifact.Name, - ExternalID: artifact.ExternalId, - } - nilSafeCopy(&value.ID, artifact.Id, identity[int64]) - if artifact.State != nil { - state := int8(*artifact.State) - value.State = &state - } - // create in DB - if err = dbConn.Create(value).Error; err != nil { - err = fmt.Errorf("error creating artifact with type_id[%d], name[%s]: %w", value.TypeID, *value.Name, err) - return nil, err - } - // create properties in DB - err = g.createArtifactProperties(ctx, value.ID, artifact.GetProperties(), false) - if err != nil { - return nil, err - } - err = g.createArtifactProperties(ctx, value.ID, artifact.GetCustomProperties(), true) - if err != nil { - return nil, err - } - artifactIds = append(artifactIds, int64(value.ID)) - } - resp = &proto.PutArtifactsResponse{ - ArtifactIds: artifactIds, - } - return resp, nil -} - -func (g grpcServer) PutExecutions(ctx context.Context, request *proto.PutExecutionsRequest) (*proto.PutExecutionsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) PutEvents(ctx context.Context, request *proto.PutEventsRequest) (*proto.PutEventsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) PutExecution(ctx context.Context, request *proto.PutExecutionRequest) (*proto.PutExecutionResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) PutLineageSubgraph(ctx context.Context, request *proto.PutLineageSubgraphRequest) (*proto.PutLineageSubgraphResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) PutContexts(ctx context.Context, request *proto.PutContextsRequest) (*proto.PutContextsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) PutAttributionsAndAssociations(ctx context.Context, request *proto.PutAttributionsAndAssociationsRequest) (*proto.PutAttributionsAndAssociationsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) PutParentContexts(ctx context.Context, request *proto.PutParentContextsRequest) (*proto.PutParentContextsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactType(ctx context.Context, request *proto.GetArtifactTypeRequest) (resp *proto.GetArtifactTypeResponse, err error) { - ctx, dbConn := service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - err = requiredFields(REQUIRED_TYPE_FIELDS, request.TypeName) - response := &proto.GetArtifactTypeResponse{} - - var results []db.Type - rx := dbConn.Find(&results, db.Type{Name: *request.TypeName, TypeKind: int8(db.ARTIFACT_TYPE), Version: request.TypeVersion}) - if rx.Error != nil { - return nil, rx.Error - } - if len(results) > 1 { - return nil, fmt.Errorf("more than one type found: %v", len(results)) - } - if len(results) == 0 { - return response, nil - } - - r0 := results[0] - artifactType := proto.ArtifactType{ - Id: &r0.ID, - Name: &r0.Name, - Version: r0.Version, - Description: r0.Description, - ExternalId: r0.ExternalID, - } - for _, v := range r0.Properties { - artifactType.Properties[v.Name] = proto.PropertyType(v.DataType) - } - response.ArtifactType = &artifactType - return response, nil -} - -func (g grpcServer) GetArtifactTypesByID(ctx context.Context, request *proto.GetArtifactTypesByIDRequest) (*proto.GetArtifactTypesByIDResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactTypes(ctx context.Context, request *proto.GetArtifactTypesRequest) (*proto.GetArtifactTypesResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionType(ctx context.Context, request *proto.GetExecutionTypeRequest) (*proto.GetExecutionTypeResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionTypesByID(ctx context.Context, request *proto.GetExecutionTypesByIDRequest) (*proto.GetExecutionTypesByIDResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionTypes(ctx context.Context, request *proto.GetExecutionTypesRequest) (*proto.GetExecutionTypesResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextType(ctx context.Context, request *proto.GetContextTypeRequest) (*proto.GetContextTypeResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextTypesByID(ctx context.Context, request *proto.GetContextTypesByIDRequest) (*proto.GetContextTypesByIDResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextTypes(ctx context.Context, request *proto.GetContextTypesRequest) (*proto.GetContextTypesResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifacts(ctx context.Context, request *proto.GetArtifactsRequest) (*proto.GetArtifactsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutions(ctx context.Context, request *proto.GetExecutionsRequest) (*proto.GetExecutionsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContexts(ctx context.Context, request *proto.GetContextsRequest) (*proto.GetContextsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactsByID(ctx context.Context, request *proto.GetArtifactsByIDRequest) (*proto.GetArtifactsByIDResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionsByID(ctx context.Context, request *proto.GetExecutionsByIDRequest) (*proto.GetExecutionsByIDResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextsByID(ctx context.Context, request *proto.GetContextsByIDRequest) (*proto.GetContextsByIDResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactsByType(ctx context.Context, request *proto.GetArtifactsByTypeRequest) (*proto.GetArtifactsByTypeResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionsByType(ctx context.Context, request *proto.GetExecutionsByTypeRequest) (*proto.GetExecutionsByTypeResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextsByType(ctx context.Context, request *proto.GetContextsByTypeRequest) (*proto.GetContextsByTypeResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactByTypeAndName(ctx context.Context, request *proto.GetArtifactByTypeAndNameRequest) (*proto.GetArtifactByTypeAndNameResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionByTypeAndName(ctx context.Context, request *proto.GetExecutionByTypeAndNameRequest) (*proto.GetExecutionByTypeAndNameResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextByTypeAndName(ctx context.Context, request *proto.GetContextByTypeAndNameRequest) (*proto.GetContextByTypeAndNameResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactsByURI(ctx context.Context, request *proto.GetArtifactsByURIRequest) (*proto.GetArtifactsByURIResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetEventsByExecutionIDs(ctx context.Context, request *proto.GetEventsByExecutionIDsRequest) (*proto.GetEventsByExecutionIDsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetEventsByArtifactIDs(ctx context.Context, request *proto.GetEventsByArtifactIDsRequest) (*proto.GetEventsByArtifactIDsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactsByExternalIds(ctx context.Context, request *proto.GetArtifactsByExternalIdsRequest) (*proto.GetArtifactsByExternalIdsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionsByExternalIds(ctx context.Context, request *proto.GetExecutionsByExternalIdsRequest) (*proto.GetExecutionsByExternalIdsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextsByExternalIds(ctx context.Context, request *proto.GetContextsByExternalIdsRequest) (*proto.GetContextsByExternalIdsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactTypesByExternalIds(ctx context.Context, request *proto.GetArtifactTypesByExternalIdsRequest) (*proto.GetArtifactTypesByExternalIdsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionTypesByExternalIds(ctx context.Context, request *proto.GetExecutionTypesByExternalIdsRequest) (*proto.GetExecutionTypesByExternalIdsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextTypesByExternalIds(ctx context.Context, request *proto.GetContextTypesByExternalIdsRequest) (*proto.GetContextTypesByExternalIdsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextsByArtifact(ctx context.Context, request *proto.GetContextsByArtifactRequest) (*proto.GetContextsByArtifactResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetContextsByExecution(ctx context.Context, request *proto.GetContextsByExecutionRequest) (*proto.GetContextsByExecutionResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetParentContextsByContext(ctx context.Context, request *proto.GetParentContextsByContextRequest) (*proto.GetParentContextsByContextResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetChildrenContextsByContext(ctx context.Context, request *proto.GetChildrenContextsByContextRequest) (*proto.GetChildrenContextsByContextResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetParentContextsByContexts(ctx context.Context, request *proto.GetParentContextsByContextsRequest) (*proto.GetParentContextsByContextsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetChildrenContextsByContexts(ctx context.Context, request *proto.GetChildrenContextsByContextsRequest) (*proto.GetChildrenContextsByContextsResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetArtifactsByContext(ctx context.Context, request *proto.GetArtifactsByContextRequest) (*proto.GetArtifactsByContextResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetExecutionsByContext(ctx context.Context, request *proto.GetExecutionsByContextRequest) (*proto.GetExecutionsByContextResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetLineageGraph(ctx context.Context, request *proto.GetLineageGraphRequest) (*proto.GetLineageGraphResponse, error) { - //TODO implement me - panic("implement me") -} - -func (g grpcServer) GetLineageSubgraph(ctx context.Context, request *proto.GetLineageSubgraphRequest) (*proto.GetLineageSubgraphResponse, error) { - //TODO implement me - panic("implement me") -} - -//nolint:golint,unused -func (g grpcServer) mustEmbedUnimplementedMetadataStoreServiceServer() { - // implemented to signal that server is extendable -} - -func (g grpcServer) createTypeProperties(ctx context.Context, properties map[string]proto.PropertyType, typeId int64) (err error) { - ctx, dbConn := service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - for propName, prop := range properties { - number := int32(prop.Number()) - property := &db.TypeProperty{ - TypeID: typeId, - Name: propName, - DataType: number, - } - if err = dbConn.Where("type_id = ? AND name = ?", typeId, propName). - Assign(property).FirstOrCreate(property).Error; err != nil { - err = fmt.Errorf("error creating type property for type_id[%d] with name[%s]: %v", typeId, propName, err) - return err - } - } - return nil -} - -func (g grpcServer) createArtifactProperties(ctx context.Context, artifactId int64, properties map[string]*proto.Value, isCustomProperty bool) (err error) { - ctx, dbConn := service.Begin(ctx, g.dbConnection) - defer handleTransaction(ctx, &err) - - for propName, prop := range properties { - property := &db.ArtifactProperty{ - ArtifactID: artifactId, - Name: propName, - } - if isCustomProperty { - property.IsCustomProperty = true - } - // TODO handle polymorphic value with null columns - intValue, ok := prop.GetValue().(*proto.Value_IntValue) - if ok { - property.IntValue = &intValue.IntValue - } - doubleValue, ok := prop.GetValue().(*proto.Value_DoubleValue) - if ok { - property.DoubleValue = &doubleValue.DoubleValue - } - stringValue, ok := prop.GetValue().(*proto.Value_StringValue) - if ok { - property.StringValue = &stringValue.StringValue - } - structValue, ok := prop.GetValue().(*proto.Value_StructValue) - if ok { - json, err2 := structValue.StructValue.MarshalJSON() - if err2 != nil { - err = fmt.Errorf("error marshaling struct %s value: %w", propName, err2) - return err - } - property.ByteValue = &json - } - protoValue, ok := prop.GetValue().(*proto.Value_ProtoValue) - if ok { - property.ProtoValue = &protoValue.ProtoValue.Value - } - boolValue, ok := prop.GetValue().(*proto.Value_BoolValue) - if ok { - property.BoolValue = &boolValue.BoolValue - } - if err = dbConn.Create(property).Error; err != nil { - err = fmt.Errorf("error creating artifact property for type_id[%d] with name %s: %v", artifactId, propName, err) - return err - } - } - return nil -} - -func identity[T int64 | string](i T) T { return i } - -func requiredFields(names []string, args ...interface{}) error { - var missing []string - for i, a := range args { - if a == nil { - missing = append(missing, names[i]) - } - } - if len(missing) > 0 { - return fmt.Errorf("missing required properties: %s", missing) - } - return nil -} - -func nilSafeCopy[D int32 | int64 | *int64 | string, S int64 | proto.Artifact_State | string](dest *D, src *S, f func(i S) D) { - if src != nil { - *dest = f(*src) - } -} -func handleTransaction(ctx context.Context, err *error) { - // handle panic - if perr := recover(); perr != nil { - _ = service.Rollback(ctx) - *err = status.Errorf(codes.Internal, "server panic: %v", perr) - return - } - if err == nil || *err == nil { - *err = service.Commit(ctx) - } else { - _ = service.Rollback(ctx) - if _, ok := status.FromError(*err); !ok { - *err = status.Errorf(codes.Internal, "internal error: %v", *err) - } - } -} diff --git a/internal/service/artifact_handler.go b/internal/service/artifact_handler.go deleted file mode 100644 index 290d5c11..00000000 --- a/internal/service/artifact_handler.go +++ /dev/null @@ -1,9 +0,0 @@ -package service - -import ( - "gorm.io/gorm" -) - -type artifactHandler struct { - db *gorm.DB -} diff --git a/internal/service/db_context.go b/internal/service/db_context.go deleted file mode 100644 index 767f6dab..00000000 --- a/internal/service/db_context.go +++ /dev/null @@ -1,85 +0,0 @@ -package service - -import ( - "context" - "fmt" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "gorm.io/gorm" -) - -type key int - -var dbKey key - -type txContext struct { - db *gorm.DB - wrapped bool -} - -// NewContext returns a new Context that carries value txContext. -func NewContext(ctx context.Context, db *gorm.DB) context.Context { - ctxDb, ok := FromContext(ctx) - if !ok { - return context.WithValue(ctx, dbKey, &txContext{db.Begin(), false}) - } - return context.WithValue(ctx, dbKey, &txContext{ctxDb, true}) -} - -// FromContext returns the gorm.DB value stored in ctx, if any. -func FromContext(ctx context.Context) (*gorm.DB, bool) { - var result *gorm.DB - tx, ok := ctx.Value(dbKey).(*txContext) - if ok { - result = tx.db - } - return result, ok -} - -func Begin(ctx context.Context, db *gorm.DB) (newCtx context.Context, dbConn *gorm.DB) { - newCtx = NewContext(ctx, db) - dbConn, _ = FromContext(newCtx) - return -} - -func Commit(ctx context.Context) error { - tx, ok := ctx.Value(dbKey).(*txContext) - if !ok { - return fmt.Errorf("missing db transaction in context %s", ctx) - } - if !tx.wrapped { - return tx.db.Commit().Error - } - // commit in unwrapped parent context - return nil -} - -func Rollback(ctx context.Context) error { - tx, ok := ctx.Value(dbKey).(*txContext) - if !ok { - return fmt.Errorf("missing db transaction in context %s", ctx) - } - if !tx.wrapped { - return tx.db.Rollback().Error - } - // rollback in unwrapped parent context - return nil -} - -func handleTransaction(ctx context.Context, err *error) { - // handle panic - if perr := recover(); perr != nil { - _ = Rollback(ctx) - *err = status.Errorf(codes.Internal, "server panic: %v", perr) - return - } - if err == nil || *err == nil { - *err = Commit(ctx) - } else { - _ = Rollback(ctx) - if _, ok := status.FromError(*err); !ok { - *err = status.Errorf(codes.Internal, "internal error: %v", *err) - } - } -} diff --git a/internal/service/db_service.go b/internal/service/db_service.go deleted file mode 100644 index 28baa391..00000000 --- a/internal/service/db_service.go +++ /dev/null @@ -1,39 +0,0 @@ -package service - -import ( - "gorm.io/gorm" - - "github.com/opendatahub-io/model-registry/internal/model/db" -) - -var _ DBService = dbServiceHandler{} -var _ DBService = (*dbServiceHandler)(nil) - -func NewDBService(db *gorm.DB) DBService { - return &dbServiceHandler{ - typeHandler: &typeHandler{db: db}, - artifactHandler: &artifactHandler{db: db}, - } -} - -type DBService interface { - InsertType(db.Type) (*db.Type, error) - UpsertType(db.Type) (*db.Type, error) - ReadType(db.Type) (*db.Type, error) - // Get-like function to use a signature similar to the gorm `Where` func - ReadAllType(query interface{}, args ...interface{}) ([]*db.Type, error) - UpdateType(db.Type) (*db.Type, error) - DeleteType(db.Type) (*db.Type, error) - - // InsertEEE(db.EEE) (*db.EEE, error) - // UpsertEEE(db.EEE) (*db.EEE, error) - // ReadEEE(db.EEE) (*db.EEE, error) - // ReadAllEEE(query interface{}, args ...interface{}) ([]*db.EEE, error) - // UpdateEEE(db.EEE) (*db.EEE, error) - // DeleteEEE(db.EEE) (*db.EEE, error) -} - -type dbServiceHandler struct { - *typeHandler - *artifactHandler -} diff --git a/internal/service/db_service_test.go b/internal/service/db_service_test.go deleted file mode 100644 index 161b8fa0..00000000 --- a/internal/service/db_service_test.go +++ /dev/null @@ -1,146 +0,0 @@ -package service - -import ( - "fmt" - "testing" - - "github.com/opendatahub-io/model-registry/internal/model/db" - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -func migrateDatabase(dbConn *gorm.DB) error { - // using only needed RDBMS type for the scope under test - err := dbConn.AutoMigrate( - db.Type{}, - db.TypeProperty{}, - // TODO: add as needed. - ) - if err != nil { - return fmt.Errorf("db migration failed: %w", err) - } - return nil -} - -func setup() (*gorm.DB, error) { - db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{}) - if err != nil { - return nil, err - } - err = migrateDatabase(db) - if err != nil { - return nil, err - } - return db, nil -} - -// Bare minimal test of PutArtifactType with a given Name, and Get. -func TestInsertTypeThenReadAllType(t *testing.T) { - dbc, err := setup() - if err != nil { - t.Errorf("Should expect DB connection: %v", err) - } - defer func() { - dbi, err := dbc.DB() - if err != nil { - t.Errorf("Test need to clear sqlite DB for the next one, but errored: %v", err) - } - dbi.Close() - }() - dal := NewDBService(dbc) - - artifactName := "John Doe" - newType := db.Type{ - Name: artifactName, - TypeKind: int8(db.ARTIFACT_TYPE), - } - - at, err := dal.InsertType(newType) - if err != nil { - t.Errorf("Should create ArtifactType: %v", err) - } - if at.ID < 0 { - t.Errorf("Should have ID for ArtifactType: %v", at.ID) - } - if at.Name != artifactName { - t.Errorf("Should have Name for ArtifactType per constant: %v", at.Name) - } - - ats, err2 := dal.ReadAllType(newType) - if err2 != nil { - t.Errorf("Should get ArtifactType: %v", err2) - } - if len(ats) != 1 { // TODO if temp file is okay, this is superfluos - t.Errorf("The test is running under different assumption") - } - at0 := ats[0] - t.Logf("at0: %v", at0) - if at0.ID != at.ID { - t.Errorf("Should have same ID") - } - if at0.Name != at.Name { - t.Errorf("Should have same Name") - } - -} - -func TestReadAllType(t *testing.T) { - dbc, err := setup() - if err != nil { - t.Errorf("Should expect DB connection: %v", err) - } - defer func() { - dbi, err := dbc.DB() - if err != nil { - t.Errorf("Test need to clear sqlite DB for the next one, but errored: %v", err) - } - dbi.Close() - }() - dal := NewDBService(dbc) - - fixVersion := "version" - - if _, err := dal.InsertType(db.Type{Name: "at0", Version: &fixVersion, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { - t.Errorf("Should create ArtifactType: %v", err) - } - if _, err := dal.InsertType(db.Type{Name: "at1", Version: &fixVersion, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { - t.Errorf("Should create ArtifactType: %v", err) - } - - results, err := dal.ReadAllType(db.Type{Version: &fixVersion}) - t.Logf("results: %v", results) - if err != nil { - t.Errorf("Should get ArtifactTypes: %v", err) - } - if len(results) != 2 { - t.Errorf("Should have retrieved 2 artifactTypes") - } -} - -func TestUpsertType(t *testing.T) { - dbc, err := setup() - if err != nil { - t.Errorf("Should expect DB connection: %v", err) - } - defer func() { - dbi, err := dbc.DB() - if err != nil { - t.Errorf("Test need to clear sqlite DB for the next one, but errored: %v", err) - } - dbi.Close() - }() - dal := NewDBService(dbc) - - artifactName := "John Doe" - v0 := "v0" - v1 := "v1" - if _, err := dal.InsertType(db.Type{Name: artifactName, Version: &v0, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { - t.Errorf("Should Insert ArtifactType: %v", err) - } - if res, err := dal.InsertType(db.Type{Name: artifactName, Version: &v0, TypeKind: int8(db.ARTIFACT_TYPE)}); err == nil { - t.Errorf("Subsequent Insert must have failed: %v", res) - } - if _, err := dal.UpsertType(db.Type{Name: artifactName, Version: &v1, TypeKind: int8(db.ARTIFACT_TYPE)}); err != nil { - t.Errorf("Should Upsert ArtifactType: %v", err) - } -} diff --git a/internal/service/type_handler.go b/internal/service/type_handler.go deleted file mode 100644 index 44b92f63..00000000 --- a/internal/service/type_handler.go +++ /dev/null @@ -1,64 +0,0 @@ -package service - -import ( - "context" - "fmt" - - "github.com/opendatahub-io/model-registry/internal/model/db" - "gorm.io/gorm" -) - -type typeHandler struct { - db *gorm.DB -} - -func (h *typeHandler) InsertType(i db.Type) (r *db.Type, err error) { - ctx, _ := Begin(context.Background(), h.db) - defer handleTransaction(ctx, &err) - - result := h.db.Create(&i) - if result.Error != nil { - return nil, result.Error - } - return &i, nil -} - -func (h *typeHandler) UpsertType(i db.Type) (r *db.Type, err error) { - ctx, _ := Begin(context.Background(), h.db) - defer handleTransaction(ctx, &err) - - if err := h.db.Where("name = ?", i.Name).Assign(i).FirstOrCreate(&i).Error; err != nil { - err = fmt.Errorf("error creating type %s: %v", i.Name, err) - return nil, err - } - return &i, nil -} - -func (h *typeHandler) ReadType(i db.Type) (*db.Type, error) { - var results []*db.Type - rx := h.db.Find(&results) - if rx.Error != nil { - return nil, rx.Error - } - if len(results) > 1 { - return nil, fmt.Errorf("found more than one Type(s): %v", len(results)) - } - return results[0], nil -} - -func (h *typeHandler) ReadAllType(query interface{}, args ...interface{}) ([]*db.Type, error) { - var results []*db.Type - rx := h.db.Where(query, args).Find(&results) - if rx.Error != nil { - return nil, rx.Error - } - return results, nil -} - -func (h *typeHandler) UpdateType(i db.Type) (result *db.Type, err error) { - panic("unimplemented") -} - -func (h *typeHandler) DeleteType(i db.Type) (r *db.Type, err error) { - panic("unimplemented") -} diff --git a/tools.go b/tools.go deleted file mode 100644 index 0ce5e195..00000000 --- a/tools.go +++ /dev/null @@ -1,11 +0,0 @@ -//go:build tools - -package tools - -import ( - _ "github.com/99designs/gqlgen" - _ "github.com/99designs/gqlgen/graphql/introspection" - _ "github.com/searKing/golang/tools/go-enum" - _ "google.golang.org/grpc/cmd/protoc-gen-go-grpc" - _ "google.golang.org/protobuf/cmd/protoc-gen-go" -) From 0394402c15239b0a94c028391fc631d616d48c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Trifir=C3=B2?= Date: Fri, 17 Nov 2023 16:39:37 +0100 Subject: [PATCH 133/254] gha: upload code coverage to codecov.io --- .github/workflows/python-client.yml | 16 +++++++++++----- clients/python/noxfile.py | 10 ++++++++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml index 12d0d14c..1e91908b 100644 --- a/.github/workflows/python-client.yml +++ b/.github/workflows/python-client.yml @@ -63,14 +63,20 @@ jobs: - name: Run Nox working-directory: clients/python run: | - nox --python=${{ matrix.python }} + if [[ ${{ matrix.session }} == "tests" ]]; then + nox --python=${{ matrix.python }} -s tests -- --cov-report=xml + else + nox --python=${{ matrix.python }} + fi - - name: Upload coverage data + - name: Upload coverage report + uses: codecov/codecov-action@v3.1.4 if: always() && matrix.session == 'tests' - uses: "actions/upload-artifact@v3" + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: - name: coverage-data - path: "clients/python/.coverage.*" + files: coverage.xml + fail_ci_if_error: true - name: Upload documentation if: matrix.session == 'docs-build' diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py index 3ddae592..1d3d5fab 100644 --- a/clients/python/noxfile.py +++ b/clients/python/noxfile.py @@ -33,9 +33,15 @@ def tests(session: Session) -> None: """Run the test suite.""" session.install(".") - session.install("coverage[toml]", "pytest", "pygments") + session.install("coverage[toml]", "pytest", "pytest-cov", "pygments") try: - session.run("coverage", "run", "--parallel", "-m", "pytest", *session.posargs) + session.run( + "pytest", + "--cov", + "--cov-config=pyproject.toml", + *session.posargs, + env={"COVERAGE_FILE": f".coverage.{session.python}"}, + ) finally: if session.interactive: session.notify("coverage", posargs=[]) From e9d05411a24ea24e66dc1b47ab7c31d907419be1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Trifir=C3=B2?= Date: Fri, 17 Nov 2023 17:30:49 +0100 Subject: [PATCH 134/254] README: add codecov badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2c574527..49e8ef2f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Model Registry ![build checks status](https://github.com/opendatahub-io/model-registry/actions/workflows/build.yml/badge.svg?branch=main) +[![codecov](https://codecov.io/github/opendatahub-io/model-registry/graph/badge.svg?token=61URLQA3VS)](https://codecov.io/github/opendatahub-io/model-registry) Model registry provides a central repository for model developers to store and manage models, versions, and artifacts metadata. A Go-based application that leverages [ml_metadata](https://github.com/google/ml-metadata/) project under the hood. From 507e93f36013387b4c0886ee9a15e833c37edba0 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Sun, 19 Nov 2023 10:13:49 +0100 Subject: [PATCH 135/254] Use canAddFields option in mlmd type setup (#160) * Use canAddFields option in mlmd type setup * Manage proxy errors * Update pkg/core/core_test.go Co-authored-by: Matteo Mortari --------- Co-authored-by: Matteo Mortari --- cmd/proxy.go | 15 +-- pkg/core/core.go | 19 ++- pkg/core/core_test.go | 289 +++++++++++++++++++++++++++++++++++++++++- 3 files changed, 307 insertions(+), 16 deletions(-) diff --git a/cmd/proxy.go b/cmd/proxy.go index ecdfa64e..aafd87b9 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -3,7 +3,6 @@ package cmd import ( "context" "fmt" - "log" "net/http" "time" @@ -29,13 +28,13 @@ hostname and port where it listens.'`, ) func runProxyServer(cmd *cobra.Command, args []string) error { - glog.Infof("Proxy server started at %s:%v", cfg.Hostname, cfg.Port) + glog.Infof("proxy server started at %s:%v", cfg.Hostname, cfg.Port) ctxTimeout, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() mlmdAddr := fmt.Sprintf("%s:%d", proxyCfg.MLMDHostname, proxyCfg.MLMDPort) - glog.Infof("Connecting to MLMD server %s..", mlmdAddr) + glog.Infof("connecting to MLMD server %s..", mlmdAddr) conn, err := grpc.DialContext( ctxTimeout, mlmdAddr, @@ -44,16 +43,14 @@ func runProxyServer(cmd *cobra.Command, args []string) error { grpc.WithTransportCredentials(insecure.NewCredentials()), ) if err != nil { - log.Fatalf("Error dialing connection to mlmd server %s: %v", mlmdAddr, err) - return err + return fmt.Errorf("error dialing connection to mlmd server %s: %v", mlmdAddr, err) } defer conn.Close() - glog.Infof("Connected to MLMD server") + glog.Infof("connected to MLMD server") service, err := core.NewModelRegistryService(conn) if err != nil { - log.Fatalf("Error creating core service: %v", err) - return err + return fmt.Errorf("error creating core service: %v", err) } ModelRegistryServiceAPIService := openapi.NewModelRegistryServiceAPIService(service) @@ -61,7 +58,7 @@ func runProxyServer(cmd *cobra.Command, args []string) error { router := openapi.NewRouter(ModelRegistryServiceAPIController) - log.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", cfg.Hostname, cfg.Port), router)) + glog.Fatal(http.ListenAndServe(fmt.Sprintf("%s:%d", cfg.Hostname, cfg.Port), router)) return nil } diff --git a/pkg/core/core.go b/pkg/core/core.go index 7c675abe..bd4350db 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -21,6 +21,7 @@ var ( servingEnvironmentTypeName = of(converter.ServingEnvironmentTypeName) inferenceServiceTypeName = of(converter.InferenceServiceTypeName) serveModelTypeName = of(converter.ServeModelTypeName) + canAddFields = of(true) ) // modelRegistryService is the core library of the model registry @@ -37,6 +38,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, // Setup the needed Type instances if not existing already registeredModelReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, ContextType: &proto.ContextType{ Name: registeredModelTypeName, Properties: map[string]proto.PropertyType{ @@ -46,6 +48,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, } modelVersionReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, ContextType: &proto.ContextType{ Name: modelVersionTypeName, Properties: map[string]proto.PropertyType{ @@ -58,6 +61,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, } modelArtifactReq := proto.PutArtifactTypeRequest{ + CanAddFields: canAddFields, ArtifactType: &proto.ArtifactType{ Name: modelArtifactTypeName, Properties: map[string]proto.PropertyType{ @@ -72,6 +76,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, } servingEnvironmentReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, ContextType: &proto.ContextType{ Name: servingEnvironmentTypeName, Properties: map[string]proto.PropertyType{ @@ -81,6 +86,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, } inferenceServiceReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, ContextType: &proto.ContextType{ Name: inferenceServiceTypeName, Properties: map[string]proto.PropertyType{ @@ -95,6 +101,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, } serveModelReq := proto.PutExecutionTypeRequest{ + CanAddFields: canAddFields, ExecutionType: &proto.ExecutionType{ Name: serveModelTypeName, Properties: map[string]proto.PropertyType{ @@ -106,32 +113,32 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, registeredModelResp, err := client.PutContextType(context.Background(), ®isteredModelReq) if err != nil { - glog.Fatalf("Error setting up context type %s: %v", *registeredModelTypeName, err) + return nil, fmt.Errorf("error setting up context type %s: %v", *registeredModelTypeName, err) } modelVersionResp, err := client.PutContextType(context.Background(), &modelVersionReq) if err != nil { - glog.Fatalf("Error setting up context type %s: %v", *modelVersionTypeName, err) + return nil, fmt.Errorf("error setting up context type %s: %v", *modelVersionTypeName, err) } modelArtifactResp, err := client.PutArtifactType(context.Background(), &modelArtifactReq) if err != nil { - glog.Fatalf("Error setting up artifact type %s: %v", *modelArtifactTypeName, err) + return nil, fmt.Errorf("error setting up artifact type %s: %v", *modelArtifactTypeName, err) } servingEnvironmentResp, err := client.PutContextType(context.Background(), &servingEnvironmentReq) if err != nil { - glog.Fatalf("Error setting up context type %s: %v", *servingEnvironmentTypeName, err) + return nil, fmt.Errorf("error setting up context type %s: %v", *servingEnvironmentTypeName, err) } inferenceServiceResp, err := client.PutContextType(context.Background(), &inferenceServiceReq) if err != nil { - glog.Fatalf("Error setting up context type %s: %v", *inferenceServiceTypeName, err) + return nil, fmt.Errorf("error setting up context type %s: %v", *inferenceServiceTypeName, err) } serveModelResp, err := client.PutExecutionType(context.Background(), &serveModelReq) if err != nil { - glog.Fatalf("Error setting up execution type %s: %v", *serveModelTypeName, err) + return nil, fmt.Errorf("error setting up execution type %s: %v", *serveModelTypeName, err) } return &modelRegistryService{ diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index 51892818..c5b9eecb 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -217,11 +217,143 @@ func registerInferenceService(assertion *assert.Assertions, service api.ModelReg return *createdEntity.Id } +func TestModelRegistryStartupWithExistingEmptyTypes(t *testing.T) { + ctx := context.Background() + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + // create all types without props + registeredModelReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: registeredModelTypeName, + }, + } + modelVersionReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: modelVersionTypeName, + }, + } + modelArtifactReq := proto.PutArtifactTypeRequest{ + CanAddFields: canAddFields, + ArtifactType: &proto.ArtifactType{ + Name: modelArtifactTypeName, + }, + } + servingEnvironmentReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: servingEnvironmentTypeName, + }, + } + inferenceServiceReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: inferenceServiceTypeName, + }, + } + serveModelReq := proto.PutExecutionTypeRequest{ + CanAddFields: canAddFields, + ExecutionType: &proto.ExecutionType{ + Name: serveModelTypeName, + }, + } + + _, err := client.PutContextType(context.Background(), ®isteredModelReq) + assertion.Nil(err) + _, err = client.PutContextType(context.Background(), &modelVersionReq) + assertion.Nil(err) + _, err = client.PutArtifactType(context.Background(), &modelArtifactReq) + assertion.Nil(err) + _, err = client.PutContextType(context.Background(), &servingEnvironmentReq) + assertion.Nil(err) + _, err = client.PutContextType(context.Background(), &inferenceServiceReq) + assertion.Nil(err) + _, err = client.PutExecutionType(context.Background(), &serveModelReq) + assertion.Nil(err) + + // check empty props + regModelResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: registeredModelTypeName, + }) + modelVersionResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: modelVersionTypeName, + }) + modelArtifactResp, _ := client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + TypeName: modelArtifactTypeName, + }) + servingEnvResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: servingEnvironmentTypeName, + }) + inferenceServiceResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: inferenceServiceTypeName, + }) + serveModelResp, _ := client.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ + TypeName: serveModelTypeName, + }) + + assertion.Equal(0, len(regModelResp.ContextType.Properties)) + assertion.Equal(0, len(modelVersionResp.ContextType.Properties)) + assertion.Equal(0, len(modelArtifactResp.ArtifactType.Properties)) + assertion.Equal(0, len(servingEnvResp.ContextType.Properties)) + assertion.Equal(0, len(inferenceServiceResp.ContextType.Properties)) + assertion.Equal(0, len(serveModelResp.ExecutionType.Properties)) + + // create model registry service + _, err = NewModelRegistryService(conn) + assertion.Nil(err) + + // assure the types have been correctly setup at startup + // check NOT empty props + regModelResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: registeredModelTypeName, + }) + assertion.NotNilf(regModelResp.ContextType, "registered model type %s should exists", *registeredModelTypeName) + assertion.Equal(*registeredModelTypeName, *regModelResp.ContextType.Name) + assertion.Equal(1, len(regModelResp.ContextType.Properties)) + + modelVersionResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: modelVersionTypeName, + }) + assertion.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) + assertion.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) + assertion.Equal(4, len(modelVersionResp.ContextType.Properties)) + + modelArtifactResp, _ = client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + TypeName: modelArtifactTypeName, + }) + assertion.NotNilf(modelArtifactResp.ArtifactType, "model artifact type %s should exists", *modelArtifactTypeName) + assertion.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) + assertion.Equal(6, len(modelArtifactResp.ArtifactType.Properties)) + + servingEnvResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: servingEnvironmentTypeName, + }) + assertion.NotNilf(servingEnvResp.ContextType, "serving environment type %s should exists", *servingEnvironmentTypeName) + assertion.Equal(*servingEnvironmentTypeName, *servingEnvResp.ContextType.Name) + assertion.Equal(1, len(servingEnvResp.ContextType.Properties)) + + inferenceServiceResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: inferenceServiceTypeName, + }) + assertion.NotNilf(inferenceServiceResp.ContextType, "inference service type %s should exists", *inferenceServiceTypeName) + assertion.Equal(*inferenceServiceTypeName, *inferenceServiceResp.ContextType.Name) + assertion.Equal(5, len(inferenceServiceResp.ContextType.Properties)) + + serveModelResp, _ = client.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ + TypeName: serveModelTypeName, + }) + assertion.NotNilf(serveModelResp.ExecutionType, "serve model type %s should exists", *serveModelTypeName) + assertion.Equal(*serveModelTypeName, *serveModelResp.ExecutionType.Name) + assertion.Equal(2, len(serveModelResp.ExecutionType.Properties)) +} + func TestModelRegistryTypes(t *testing.T) { assertion, conn, client, teardown := setup(t) defer teardown(t) - // create mode registry service + // create model registry service _ = initModelRegistryService(assertion, conn) // assure the types have been correctly setup at startup @@ -243,6 +375,161 @@ func TestModelRegistryTypes(t *testing.T) { }) assertion.NotNilf(modelArtifactResp.ArtifactType, "model version type %s should exists", *modelArtifactTypeName) assertion.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) + + servingEnvResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: servingEnvironmentTypeName, + }) + assertion.NotNilf(servingEnvResp.ContextType, "serving environment type %s should exists", *servingEnvironmentTypeName) + assertion.Equal(*servingEnvironmentTypeName, *servingEnvResp.ContextType.Name) + + inferenceServiceResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + TypeName: inferenceServiceTypeName, + }) + assertion.NotNilf(inferenceServiceResp.ContextType, "inference service type %s should exists", *inferenceServiceTypeName) + assertion.Equal(*inferenceServiceTypeName, *inferenceServiceResp.ContextType.Name) + + serveModelResp, _ := client.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ + TypeName: serveModelTypeName, + }) + assertion.NotNilf(serveModelResp.ExecutionType, "serve model type %s should exists", *serveModelTypeName) + assertion.Equal(*serveModelTypeName, *serveModelResp.ExecutionType.Name) +} + +func TestModelRegistryFailureForOmittedFieldInRegisteredModel(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + registeredModelReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: registeredModelTypeName, + Properties: map[string]proto.PropertyType{ + "deprecated": proto.PropertyType_STRING, + }, + }, + } + + _, err := client.PutContextType(context.Background(), ®isteredModelReq) + assertion.Nil(err) + + // create model registry service + _, err = NewModelRegistryService(conn) + assertion.NotNil(err) + assertion.Regexp("error setting up context type odh.RegisteredModel: rpc error: code = AlreadyExists.*", err.Error()) +} + +func TestModelRegistryFailureForOmittedFieldInModelVersion(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + modelVersionReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: modelVersionTypeName, + Properties: map[string]proto.PropertyType{ + "deprecated": proto.PropertyType_STRING, + }, + }, + } + + _, err := client.PutContextType(context.Background(), &modelVersionReq) + assertion.Nil(err) + + // create model registry service + _, err = NewModelRegistryService(conn) + assertion.NotNil(err) + assertion.Regexp("error setting up context type odh.ModelVersion: rpc error: code = AlreadyExists.*", err.Error()) +} + +func TestModelRegistryFailureForOmittedFieldInModelArtifact(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + modelArtifactReq := proto.PutArtifactTypeRequest{ + CanAddFields: canAddFields, + ArtifactType: &proto.ArtifactType{ + Name: modelArtifactTypeName, + Properties: map[string]proto.PropertyType{ + "deprecated": proto.PropertyType_STRING, + }, + }, + } + + _, err := client.PutArtifactType(context.Background(), &modelArtifactReq) + assertion.Nil(err) + + // create model registry service + _, err = NewModelRegistryService(conn) + assertion.NotNil(err) + assertion.Regexp("error setting up artifact type odh.ModelArtifact: rpc error: code = AlreadyExists.*", err.Error()) +} + +func TestModelRegistryFailureForOmittedFieldInServingEnvironment(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + servingEnvironmentReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: servingEnvironmentTypeName, + Properties: map[string]proto.PropertyType{ + "deprecated": proto.PropertyType_STRING, + }, + }, + } + _, err := client.PutContextType(context.Background(), &servingEnvironmentReq) + assertion.Nil(err) + + // create model registry service + _, err = NewModelRegistryService(conn) + assertion.NotNil(err) + assertion.Regexp("error setting up context type odh.ServingEnvironment: rpc error: code = AlreadyExists.*", err.Error()) +} + +func TestModelRegistryFailureForOmittedFieldInInferenceService(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + inferenceServiceReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: inferenceServiceTypeName, + Properties: map[string]proto.PropertyType{ + "deprecated": proto.PropertyType_STRING, + }, + }, + } + + _, err := client.PutContextType(context.Background(), &inferenceServiceReq) + assertion.Nil(err) + + // create model registry service + _, err = NewModelRegistryService(conn) + assertion.NotNil(err) + assertion.Regexp("error setting up context type odh.InferenceService: rpc error: code = AlreadyExists.*", err.Error()) +} + +func TestModelRegistryFailureForOmittedFieldInServeModel(t *testing.T) { + assertion, conn, client, teardown := setup(t) + defer teardown(t) + + serveModelReq := proto.PutExecutionTypeRequest{ + CanAddFields: canAddFields, + ExecutionType: &proto.ExecutionType{ + Name: serveModelTypeName, + Properties: map[string]proto.PropertyType{ + "deprecated": proto.PropertyType_STRING, + }, + }, + } + + _, err := client.PutExecutionType(context.Background(), &serveModelReq) + assertion.Nil(err) + + // create model registry service + _, err = NewModelRegistryService(conn) + assertion.NotNil(err) + assertion.Regexp("error setting up execution type odh.ServeModel: rpc error: code = AlreadyExists.*", err.Error()) } // REGISTERED MODELS From 9feaaf9ed2a889569cf10f33e5b6e62aee9fde0e Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Sun, 19 Nov 2023 10:17:27 +0100 Subject: [PATCH 136/254] Fix GetModelArtifactByParams when no results (#165) --- pkg/core/core.go | 12 ++++++-- pkg/core/core_test.go | 66 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/pkg/core/core.go b/pkg/core/core.go index bd4350db..87ee2acc 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -699,9 +699,15 @@ func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, if err != nil { return nil, err } + if len(artifactsResponse.Artifacts) > 1 { - return nil, fmt.Errorf("more than an artifact detected matching criteria: %v", artifactsResponse.Artifacts) + return nil, fmt.Errorf("multiple model artifacts found for artifactName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(artifactName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + } + + if len(artifactsResponse.Artifacts) == 0 { + return nil, fmt.Errorf("no model artifacts found for artifactName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(artifactName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) } + artifact0 = artifactsResponse.Artifacts[0] result, err := serv.mapper.MapToModelArtifact(artifact0) @@ -1072,11 +1078,11 @@ func (serv *modelRegistryService) GetInferenceServiceByParams(name *string, pare } if len(getByParamsResp.Contexts) > 1 { - return nil, fmt.Errorf("multiple inference services found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("multiple inference services found for name=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) } if len(getByParamsResp.Contexts) == 0 { - return nil, fmt.Errorf("no inference services found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("no inference services found for name=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) } toReturn, err := serv.mapper.MapToInferenceService(getByParamsResp.Contexts[0]) diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index c5b9eecb..aae040e3 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -706,6 +706,18 @@ func TestGetRegisteredModelById(t *testing.T) { assertion.Equal(*registeredModel.CustomProperties, *getModelById.CustomProperties, "saved model custom props should match the original one") } +func TestGetRegisteredModelByParamsWithNoResults(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + _, err := service.GetRegisteredModelByParams(of("not-present"), nil) + assertion.NotNil(err) + assertion.Equal("no registered models found for name=not-present, externalId=", err.Error()) +} + func TestGetRegisteredModelByParamsName(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) @@ -1198,6 +1210,20 @@ func TestGetModelVersionById(t *testing.T) { assertion.Equal(*(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, author, "saved author custom property should match the provided one") } +func TestGetModelVersionByParamsWithNoResults(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + registeredModelId := registerModel(assertion, service, nil, nil) + + _, err := service.GetModelVersionByParams(of("not-present"), ®isteredModelId, nil) + assertion.NotNil(err) + assertion.Equal("no model versions found for versionName=not-present, parentResourceId=1, externalId=", err.Error()) +} + func TestGetModelVersionByParamsName(t *testing.T) { assertion, conn, client, teardown := setup(t) defer teardown(t) @@ -1726,6 +1752,20 @@ func TestGetModelArtifactByEmptyParams(t *testing.T) { assertion.Equal("invalid parameters call, supply either (artifactName and parentResourceId), or externalId", err.Error()) } +func TestGetModelArtifactByParamsWithNoResults(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + + _, err := service.GetModelArtifactByParams(of("not-present"), &modelVersionId, nil) + assertion.NotNil(err) + assertion.Equal("no model artifacts found for artifactName=not-present, parentResourceId=2, externalId=", err.Error()) +} + func TestGetModelArtifacts(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) @@ -1989,6 +2029,18 @@ func TestGetServingEnvironmentById(t *testing.T) { assertion.Equal(*eut.CustomProperties, *getEntityById.CustomProperties, "saved custom props should match the original one") } +func TestGetServingEnvironmentByParamsWithNoResults(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + _, err := service.GetServingEnvironmentByParams(of("not-present"), nil) + assertion.NotNil(err) + assertion.Equal("no serving environments found for name=not-present, externalId=", err.Error()) +} + func TestGetServingEnvironmentByParamsName(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) @@ -2595,6 +2647,20 @@ func TestGetModelVersionByInferenceServiceId(t *testing.T) { assertion.Equal(createdVersion1Id, *getVModel.Id, "returned id shall be the specified one") } +func TestGetInferenceServiceByParamsWithNoResults(t *testing.T) { + assertion, conn, _, teardown := setup(t) + defer teardown(t) + + // create mode registry service + service := initModelRegistryService(assertion, conn) + + parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + + _, err := service.GetInferenceServiceByParams(of("not-present"), &parentResourceId, nil) + assertion.NotNil(err) + assertion.Equal("no inference services found for name=not-present, parentResourceId=1, externalId=", err.Error()) +} + func TestGetInferenceServiceByParamsName(t *testing.T) { assertion, conn, client, teardown := setup(t) defer teardown(t) From 36fe1f36bd9b89e4143c4db9c0c9a7b0226b1cad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Trifir=C3=B2?= Date: Mon, 20 Nov 2023 12:27:36 +0100 Subject: [PATCH 137/254] gha: set up go code coverage using codecov.io --- .github/workflows/build.yml | 9 ++++++++- Makefile | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5dc2d7ab..5ed8087c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,4 +51,11 @@ jobs: exit 1 fi - name: Unit tests - run: make test + run: make test-cover + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3.1.4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + with: + files: coverage.txt + fail_ci_if_error: true diff --git a/Makefile b/Makefile index 8cf4b62a..c38838e3 100644 --- a/Makefile +++ b/Makefile @@ -166,7 +166,7 @@ test-nocache: gen .PHONY: test-cover test-cover: gen - go test ./internal/... ./pkg/... -cover -count=1 + go test ./internal/... ./pkg/... -cover -count=1 -race -coverprofile=coverage.txt -covermode=atomic .PHONY: run/proxy run/proxy: gen From b9d8808ba2c78d9f81a8457e16cd23ae23857a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Trifir=C3=B2?= Date: Mon, 20 Nov 2023 15:25:39 +0100 Subject: [PATCH 138/254] gha: always run python tests this is done in order to have accurate code coverage reports on pull requests. --- .github/workflows/python-client.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml index 1e91908b..73082562 100644 --- a/.github/workflows/python-client.yml +++ b/.github/workflows/python-client.yml @@ -5,9 +5,6 @@ on: branches: - "main" pull_request: - paths: - - "clients/python/**" - - ".github/workflows/python-client.yml" jobs: tests: From 6f4d25d226432c970a106926052fd0957c057263 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Sat, 18 Nov 2023 22:22:37 +0100 Subject: [PATCH 139/254] Fix strict symbol validation in MR Python client --- .../python/src/model_registry/store/wrapper.py | 17 +++++++++-------- .../python/src/model_registry/types/options.py | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index 0db1a761..9028ef53 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -1,7 +1,8 @@ from collections.abc import Sequence from typing import Optional -from ml_metadata import ListOptions, MetadataStore, errors +from ml_metadata.metadata_store import ListOptions, MetadataStore +from ml_metadata import errors from ml_metadata.proto import ( Artifact, Attribution, @@ -167,7 +168,7 @@ def get_context(self, ctx_type_name: str, elif external_id is not None: contexts = self._mlmd_store.get_contexts_by_external_ids([external_id]) else: - raise StoreError("Either id, name or external_id must be provided") + raise StoreException("Either id, name or external_id must be provided") contexts = self._filter_type(ctx_type_name, contexts) if contexts: @@ -183,16 +184,16 @@ def get_contexts( try: contexts = self._mlmd_store.get_contexts(options) except errors.InvalidArgumentError as e: - raise StoreError(f"Invalid arguments for get_contexts: {e}") from e + raise StoreException(f"Invalid arguments for get_contexts: {e}") from e except errors.InternalError as e: - raise ServerError("Couldn't get contexts from MLMD store") from e + raise ServerException("Couldn't get contexts from MLMD store") from e contexts = self._filter_type(ctx_type_name, contexts) # else: # contexts = self._mlmd_store.get_contexts_by_type(ctx_type_name) if not contexts: - raise StoreError(f"Context type {ctx_type_name} does not exist") + raise StoreException(f"Context type {ctx_type_name} does not exist") return contexts @@ -296,12 +297,12 @@ def get_artifacts( try: artifacts = self._mlmd_store.get_artifacts(options) except errors.InvalidArgumentError as e: - raise StoreError(f"Invalid arguments for get_artifacts: {e}") from e + raise StoreException(f"Invalid arguments for get_artifacts: {e}") from e except errors.InternalError as e: - raise ServerError("Couldn't get artifacts from MLMD store") from e + raise ServerException("Couldn't get artifacts from MLMD store") from e artifacts = self._filter_type(art_type_name, artifacts) if not artifacts: - raise StoreError(f"Artifact type {art_type_name} does not exist") + raise StoreException(f"Artifact type {art_type_name} does not exist") return artifacts diff --git a/clients/python/src/model_registry/types/options.py b/clients/python/src/model_registry/types/options.py index aaae7c5b..8b1a17c9 100644 --- a/clients/python/src/model_registry/types/options.py +++ b/clients/python/src/model_registry/types/options.py @@ -7,8 +7,8 @@ from enum import Enum from typing import Optional -from ml_metadata import ListOptions as MLMDListOptions -from ml_metadata import OrderByField as MLMDOrderByField +from ml_metadata.metadata_store import ListOptions as MLMDListOptions +from ml_metadata.metadata_store import OrderByField as MLMDOrderByField class OrderByField(Enum): From 5afff25b8eb04f5b58c7d0c765c2f5bf1adb25e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Trifir=C3=B2?= Date: Tue, 21 Nov 2023 15:47:23 +0100 Subject: [PATCH 140/254] python client: remove duplicated imports --- clients/python/src/model_registry/store/wrapper.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index 9028ef53..8be124d9 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -10,13 +10,6 @@ MetadataStoreClientConfig, ParentContext, ) -from ml_metadata.proto import ( - Artifact, - Attribution, - Context, - MetadataStoreClientConfig, - ParentContext, -) from .base import ProtoType from model_registry.exceptions import ( From 3ac38fc34e2e23b7b5ec42f9f794a754842fd117 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Trifir=C3=B2?= Date: Tue, 21 Nov 2023 16:04:18 +0100 Subject: [PATCH 141/254] python client: improve ci by running a linting step --- .github/workflows/python-client.yml | 10 ++++++++++ clients/python/noxfile.py | 17 ++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml index 73082562..5f5e8c52 100644 --- a/.github/workflows/python-client.yml +++ b/.github/workflows/python-client.yml @@ -57,6 +57,16 @@ jobs: pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry nox --version + - name: Lint + working-directory: clients/python + if: matrix.session == 'tests' + run: | + nox --python=${{ matrix.python }} -s lint + nox --python=${{ matrix.python }} -s mypy || failure=true + if [[ -n $failure ]]; then + echo "::error title='mypy failure'::Check the logs for more details" + fi + - name: Run Nox working-directory: clients/python run: | diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py index 1d3d5fab..695283d2 100644 --- a/clients/python/noxfile.py +++ b/clients/python/noxfile.py @@ -7,7 +7,6 @@ import nox - try: from nox_poetry import Session, session except ImportError: @@ -29,6 +28,22 @@ ) +@session(python=python_versions) +def lint(session: Session) -> None: + """lint using ruff and mypy""" + session.install(".", "ruff") + + session.run("ruff", "check", "src") + + +@session +def mypy(session: Session) -> None: + """lint using ruff and mypy""" + session.install(".", "mypy") + + session.run("mypy", "src") + + @session(python=python_versions) def tests(session: Session) -> None: """Run the test suite.""" From 7deb5a38ebfcc2dac803eae0fbf439835aac09b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Trifir=C3=B2?= Date: Tue, 21 Nov 2023 16:07:47 +0100 Subject: [PATCH 142/254] python client: add target-version to ruff config --- clients/python/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 0bfe9476..24792ba9 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -38,6 +38,7 @@ build-backend = "poetry.core.masonry.api" line-length = 119 [tool.ruff] +target-version = "py39" ignore = ["E501"] [tool.ruff.mccabe] From 9f23f30e9500410f80cefeda9d46ef69186fa4cb Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Wed, 22 Nov 2023 18:13:40 +0100 Subject: [PATCH 143/254] Fix format logging and make ModelRegistryService public (#183) * Fix format logging * Make ModelRegistryService public --- internal/mapper/mapper.go | 2 +- pkg/core/core.go | 96 ++++++++++++++++++++------------------- pkg/core/core_test.go | 2 +- 3 files changed, 51 insertions(+), 49 deletions(-) diff --git a/internal/mapper/mapper.go b/internal/mapper/mapper.go index 865c48d8..caccefef 100644 --- a/internal/mapper/mapper.go +++ b/internal/mapper/mapper.go @@ -102,7 +102,7 @@ func (m *Mapper) MapFromServingEnvironment(servingEnvironment *openapi.ServingEn return ctx, nil } -func (m *Mapper) MapFromInferenceService(inferenceService *openapi.InferenceService, servingEnvironmentId string, servingEnvironmentName *string) (*proto.Context, error) { +func (m *Mapper) MapFromInferenceService(inferenceService *openapi.InferenceService, servingEnvironmentId string) (*proto.Context, error) { ctx, err := m.OpenAPIConverter.ConvertInferenceService(&converter.OpenAPIModelWrapper[openapi.InferenceService]{ TypeId: m.InferenceServiceTypeId, Model: inferenceService, diff --git a/pkg/core/core.go b/pkg/core/core.go index 87ee2acc..4c8116ef 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -24,8 +24,8 @@ var ( canAddFields = of(true) ) -// modelRegistryService is the core library of the model registry -type modelRegistryService struct { +// ModelRegistryService is the core library of the model registry +type ModelRegistryService struct { mlmdClient proto.MetadataStoreServiceClient mapper *mapper.Mapper } @@ -141,7 +141,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, return nil, fmt.Errorf("error setting up execution type %s: %v", *serveModelTypeName, err) } - return &modelRegistryService{ + return &ModelRegistryService{ mlmdClient: client, mapper: mapper.NewMapper( registeredModelResp.GetTypeId(), @@ -156,14 +156,14 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, // REGISTERED MODELS -func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) { +func (serv *ModelRegistryService) UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) { var err error var existing *openapi.RegisteredModel if registeredModel.Id == nil { glog.Info("Creating new registered model") } else { - glog.Info("Updating registered model %s", *registeredModel.Id) + glog.Infof("Updating registered model %s", *registeredModel.Id) existing, err = serv.GetRegisteredModelById(*registeredModel.Id) if err != nil { return nil, err @@ -200,8 +200,8 @@ func (serv *modelRegistryService) UpsertRegisteredModel(registeredModel *openapi return model, nil } -func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) { - glog.Info("Getting registered model %s", id) +func (serv *ModelRegistryService) GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) { + glog.Infof("Getting registered model %s", id) idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -231,7 +231,7 @@ func (serv *modelRegistryService) GetRegisteredModelById(id string) (*openapi.Re return regModel, nil } -func (serv *modelRegistryService) GetRegisteredModelByInferenceService(inferenceServiceId string) (*openapi.RegisteredModel, error) { +func (serv *ModelRegistryService) GetRegisteredModelByInferenceService(inferenceServiceId string) (*openapi.RegisteredModel, error) { is, err := serv.GetInferenceServiceById(inferenceServiceId) if err != nil { return nil, err @@ -239,8 +239,8 @@ func (serv *modelRegistryService) GetRegisteredModelByInferenceService(inference return serv.GetRegisteredModelById(is.RegisteredModelId) } -func (serv *modelRegistryService) getRegisteredModelByVersionId(id string) (*openapi.RegisteredModel, error) { - glog.Info("Getting registered model for model version %s", id) +func (serv *ModelRegistryService) getRegisteredModelByVersionId(id string) (*openapi.RegisteredModel, error) { + glog.Infof("Getting registered model for model version %s", id) idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -270,8 +270,8 @@ func (serv *modelRegistryService) getRegisteredModelByVersionId(id string) (*ope return regModel, nil } -func (serv *modelRegistryService) GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) { - glog.Info("Getting registered model by params name=%v, externalId=%v", name, externalId) +func (serv *ModelRegistryService) GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) { + glog.Infof("Getting registered model by params name=%v, externalId=%v", name, externalId) filterQuery := "" if name != nil { @@ -307,7 +307,7 @@ func (serv *modelRegistryService) GetRegisteredModelByParams(name *string, exter return regModel, nil } -func (serv *modelRegistryService) GetRegisteredModels(listOptions api.ListOptions) (*openapi.RegisteredModelList, error) { +func (serv *ModelRegistryService) GetRegisteredModels(listOptions api.ListOptions) (*openapi.RegisteredModelList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -340,7 +340,7 @@ func (serv *modelRegistryService) GetRegisteredModels(listOptions api.ListOption // MODEL VERSIONS -func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *string) (*openapi.ModelVersion, error) { +func (serv *ModelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *string) (*openapi.ModelVersion, error) { var err error var existing *openapi.ModelVersion var registeredModel *openapi.RegisteredModel @@ -357,7 +357,7 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model } } else { // update - glog.Info("Updating model version %s", *modelVersion.Id) + glog.Infof("Updating model version %s", *modelVersion.Id) existing, err = serv.GetModelVersionById(*modelVersion.Id) if err != nil { return nil, err @@ -416,7 +416,7 @@ func (serv *modelRegistryService) UpsertModelVersion(modelVersion *openapi.Model return model, nil } -func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.ModelVersion, error) { +func (serv *ModelRegistryService) GetModelVersionById(id string) (*openapi.ModelVersion, error) { idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err @@ -445,7 +445,7 @@ func (serv *modelRegistryService) GetModelVersionById(id string) (*openapi.Model return modelVer, nil } -func (serv *modelRegistryService) GetModelVersionByInferenceService(inferenceServiceId string) (*openapi.ModelVersion, error) { +func (serv *ModelRegistryService) GetModelVersionByInferenceService(inferenceServiceId string) (*openapi.ModelVersion, error) { is, err := serv.GetInferenceServiceById(inferenceServiceId) if err != nil { return nil, err @@ -466,8 +466,8 @@ func (serv *modelRegistryService) GetModelVersionByInferenceService(inferenceSer return &versions.Items[0], nil } -func (serv *modelRegistryService) getModelVersionByArtifactId(id string) (*openapi.ModelVersion, error) { - glog.Info("Getting model version for model artifact %s", id) +func (serv *ModelRegistryService) getModelVersionByArtifactId(id string) (*openapi.ModelVersion, error) { + glog.Infof("Getting model version for model artifact %s", id) idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -497,7 +497,7 @@ func (serv *modelRegistryService) getModelVersionByArtifactId(id string) (*opena return modelVersion, nil } -func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) { +func (serv *ModelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) { filterQuery := "" if versionName != nil && parentResourceId != nil { filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *versionName)) @@ -532,7 +532,7 @@ func (serv *modelRegistryService) GetModelVersionByParams(versionName *string, p return modelVer, nil } -func (serv *modelRegistryService) GetModelVersions(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) { +func (serv *ModelRegistryService) GetModelVersions(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -571,7 +571,7 @@ func (serv *modelRegistryService) GetModelVersions(listOptions api.ListOptions, // MODEL ARTIFACTS -func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *string) (*openapi.ModelArtifact, error) { +func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *string) (*openapi.ModelArtifact, error) { var err error var existing *openapi.ModelArtifact @@ -587,7 +587,7 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } } else { // update - glog.Info("Updating model artifact %s", *modelArtifact.Id) + glog.Infof("Updating model artifact %s", *modelArtifact.Id) existing, err = serv.GetModelArtifactById(*modelArtifact.Id) if err != nil { return nil, err @@ -649,7 +649,7 @@ func (serv *modelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod return mapped, nil } -func (serv *modelRegistryService) GetModelArtifactById(id string) (*openapi.ModelArtifact, error) { +func (serv *ModelRegistryService) GetModelArtifactById(id string) (*openapi.ModelArtifact, error) { idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err @@ -678,7 +678,7 @@ func (serv *modelRegistryService) GetModelArtifactById(id string) (*openapi.Mode return result, nil } -func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, parentResourceId *string, externalId *string) (*openapi.ModelArtifact, error) { +func (serv *ModelRegistryService) GetModelArtifactByParams(artifactName *string, parentResourceId *string, externalId *string) (*openapi.ModelArtifact, error) { var artifact0 *proto.Artifact filterQuery := "" @@ -718,7 +718,7 @@ func (serv *modelRegistryService) GetModelArtifactByParams(artifactName *string, return result, nil } -func (serv *modelRegistryService) GetModelArtifacts(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) { +func (serv *ModelRegistryService) GetModelArtifacts(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -772,14 +772,14 @@ func (serv *modelRegistryService) GetModelArtifacts(listOptions api.ListOptions, // SERVING ENVIRONMENT -func (serv *modelRegistryService) UpsertServingEnvironment(servingEnvironment *openapi.ServingEnvironment) (*openapi.ServingEnvironment, error) { +func (serv *ModelRegistryService) UpsertServingEnvironment(servingEnvironment *openapi.ServingEnvironment) (*openapi.ServingEnvironment, error) { var err error var existing *openapi.ServingEnvironment if servingEnvironment.Id == nil { glog.Info("Creating new serving environment") } else { - glog.Info("Updating serving environment %s", *servingEnvironment.Id) + glog.Infof("Updating serving environment %s", *servingEnvironment.Id) existing, err = serv.GetServingEnvironmentById(*servingEnvironment.Id) if err != nil { return nil, err @@ -816,8 +816,8 @@ func (serv *modelRegistryService) UpsertServingEnvironment(servingEnvironment *o return openapiModel, nil } -func (serv *modelRegistryService) GetServingEnvironmentById(id string) (*openapi.ServingEnvironment, error) { - glog.Info("Getting serving environment %s", id) +func (serv *ModelRegistryService) GetServingEnvironmentById(id string) (*openapi.ServingEnvironment, error) { + glog.Infof("Getting serving environment %s", id) idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -847,8 +847,8 @@ func (serv *modelRegistryService) GetServingEnvironmentById(id string) (*openapi return openapiModel, nil } -func (serv *modelRegistryService) GetServingEnvironmentByParams(name *string, externalId *string) (*openapi.ServingEnvironment, error) { - glog.Info("Getting serving environment by params name=%v, externalId=%v", name, externalId) +func (serv *ModelRegistryService) GetServingEnvironmentByParams(name *string, externalId *string) (*openapi.ServingEnvironment, error) { + glog.Infof("Getting serving environment by params name=%v, externalId=%v", name, externalId) filterQuery := "" if name != nil { @@ -884,7 +884,7 @@ func (serv *modelRegistryService) GetServingEnvironmentByParams(name *string, ex return openapiModel, nil } -func (serv *modelRegistryService) GetServingEnvironments(listOptions api.ListOptions) (*openapi.ServingEnvironmentList, error) { +func (serv *ModelRegistryService) GetServingEnvironments(listOptions api.ListOptions) (*openapi.ServingEnvironmentList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -917,7 +917,7 @@ func (serv *modelRegistryService) GetServingEnvironments(listOptions api.ListOpt // INFERENCE SERVICE -func (serv *modelRegistryService) UpsertInferenceService(inferenceService *openapi.InferenceService) (*openapi.InferenceService, error) { +func (serv *ModelRegistryService) UpsertInferenceService(inferenceService *openapi.InferenceService) (*openapi.InferenceService, error) { var err error var existing *openapi.InferenceService var servingEnvironment *openapi.ServingEnvironment @@ -933,7 +933,7 @@ func (serv *modelRegistryService) UpsertInferenceService(inferenceService *opena } } else { // update - glog.Info("Updating InferenceService %s", *inferenceService.Id) + glog.Infof("Updating InferenceService %s", *inferenceService.Id) existing, err = serv.GetInferenceServiceById(*inferenceService.Id) if err != nil { return nil, err @@ -956,7 +956,7 @@ func (serv *modelRegistryService) UpsertInferenceService(inferenceService *opena inferenceService.Name = existing.Name } - protoCtx, err := serv.mapper.MapFromInferenceService(inferenceService, *servingEnvironment.Id, servingEnvironment.Name) + protoCtx, err := serv.mapper.MapFromInferenceService(inferenceService, *servingEnvironment.Id) if err != nil { return nil, err } @@ -997,8 +997,8 @@ func (serv *modelRegistryService) UpsertInferenceService(inferenceService *opena return toReturn, nil } -func (serv *modelRegistryService) getServingEnvironmentByInferenceServiceId(id string) (*openapi.ServingEnvironment, error) { - glog.Info("Getting ServingEnvironment for InferenceService %s", id) +func (serv *ModelRegistryService) getServingEnvironmentByInferenceServiceId(id string) (*openapi.ServingEnvironment, error) { + glog.Infof("Getting ServingEnvironment for InferenceService %s", id) idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -1028,7 +1028,9 @@ func (serv *modelRegistryService) getServingEnvironmentByInferenceServiceId(id s return toReturn, nil } -func (serv *modelRegistryService) GetInferenceServiceById(id string) (*openapi.InferenceService, error) { +func (serv *ModelRegistryService) GetInferenceServiceById(id string) (*openapi.InferenceService, error) { + glog.Infof("Getting InferenceService by id %s", id) + idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err @@ -1057,7 +1059,7 @@ func (serv *modelRegistryService) GetInferenceServiceById(id string) (*openapi.I return toReturn, nil } -func (serv *modelRegistryService) GetInferenceServiceByParams(name *string, parentResourceId *string, externalId *string) (*openapi.InferenceService, error) { +func (serv *ModelRegistryService) GetInferenceServiceByParams(name *string, parentResourceId *string, externalId *string) (*openapi.InferenceService, error) { filterQuery := "" if name != nil && parentResourceId != nil { filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *name)) @@ -1092,7 +1094,7 @@ func (serv *modelRegistryService) GetInferenceServiceByParams(name *string, pare return toReturn, nil } -func (serv *modelRegistryService) GetInferenceServices(listOptions api.ListOptions, parentResourceId *string) (*openapi.InferenceServiceList, error) { +func (serv *ModelRegistryService) GetInferenceServices(listOptions api.ListOptions, parentResourceId *string) (*openapi.InferenceServiceList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -1131,7 +1133,7 @@ func (serv *modelRegistryService) GetInferenceServices(listOptions api.ListOptio // SERVE MODEL -func (serv *modelRegistryService) UpsertServeModel(serveModel *openapi.ServeModel, parentResourceId *string) (*openapi.ServeModel, error) { +func (serv *ModelRegistryService) UpsertServeModel(serveModel *openapi.ServeModel, parentResourceId *string) (*openapi.ServeModel, error) { var err error var existing *openapi.ServeModel @@ -1147,7 +1149,7 @@ func (serv *modelRegistryService) UpsertServeModel(serveModel *openapi.ServeMode } } else { // update - glog.Info("Updating ServeModel %s", *serveModel.Id) + glog.Infof("Updating ServeModel %s", *serveModel.Id) existing, err = serv.GetServeModelById(*serveModel.Id) if err != nil { return nil, err @@ -1211,8 +1213,8 @@ func (serv *modelRegistryService) UpsertServeModel(serveModel *openapi.ServeMode return mapped, nil } -func (serv *modelRegistryService) getInferenceServiceByServeModel(id string) (*openapi.InferenceService, error) { - glog.Info("Getting InferenceService for ServeModel %s", id) +func (serv *ModelRegistryService) getInferenceServiceByServeModel(id string) (*openapi.InferenceService, error) { + glog.Infof("Getting InferenceService for ServeModel %s", id) idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -1242,7 +1244,7 @@ func (serv *modelRegistryService) getInferenceServiceByServeModel(id string) (*o return toReturn, nil } -func (serv *modelRegistryService) GetServeModelById(id string) (*openapi.ServeModel, error) { +func (serv *ModelRegistryService) GetServeModelById(id string) (*openapi.ServeModel, error) { idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err @@ -1271,7 +1273,7 @@ func (serv *modelRegistryService) GetServeModelById(id string) (*openapi.ServeMo return result, nil } -func (serv *modelRegistryService) GetServeModels(listOptions api.ListOptions, parentResourceId *string) (*openapi.ServeModelList, error) { +func (serv *ModelRegistryService) GetServeModels(listOptions api.ListOptions, parentResourceId *string) (*openapi.ServeModelList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index aae040e3..0ad12243 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -2594,7 +2594,7 @@ func TestGetRegisteredModelByInferenceServiceId(t *testing.T) { func TestGetModelVersionByInferenceServiceId(t *testing.T) { assertion, conn, _, teardown := setup(t) defer teardown(t) - // todo + // create mode registry service service := initModelRegistryService(assertion, conn) From 11a774947f3aad7e4f32ad59856213f1cef922a6 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Thu, 16 Nov 2023 10:15:23 +0000 Subject: [PATCH 144/254] Refactor robot test to use REST Vs Python variants --- test/robot/MLMetadata.py | 11 ++- test/robot/MRandLogicalModel.robot | 18 ++-- test/robot/MRkeywords.resource | 131 +++++++++++++++++++++++++++++ test/robot/MRviaPython.resource | 17 ---- test/robot/MRviaREST.resource | 52 ------------ test/robot/ModelRegistry.py | 41 +++++++++ test/robot/UserStory.robot | 61 +++++++++++--- test/robot/data.yaml | 9 ++ 8 files changed, 247 insertions(+), 93 deletions(-) create mode 100644 test/robot/MRkeywords.resource delete mode 100644 test/robot/MRviaPython.resource delete mode 100644 test/robot/MRviaREST.resource create mode 100644 test/robot/ModelRegistry.py create mode 100644 test/robot/data.yaml diff --git a/test/robot/MLMetadata.py b/test/robot/MLMetadata.py index fdae3f20..0d2ccc28 100644 --- a/test/robot/MLMetadata.py +++ b/test/robot/MLMetadata.py @@ -1,10 +1,19 @@ from ml_metadata.metadata_store import metadata_store +from ml_metadata.metadata_store.metadata_store import ListOptions from ml_metadata.proto import metadata_store_pb2 +from ml_metadata import proto +from typing import List, Optional class MLMetadata(metadata_store.MetadataStore): - def __init__(self, host: str = 'localhost', port: int = 8081): + def __init__(self, host: str = 'localhost', port: int = 9090): client_connection_config = metadata_store_pb2.MetadataStoreClientConfig() client_connection_config.host = host client_connection_config.port = port print(client_connection_config) super().__init__(client_connection_config) + + def get_contexts_by_single_id(self, context_id: int) -> List[proto.Context]: + return self.get_contexts_by_id([context_id]) + + def get_artifacts_by_single_id(self, artifact_id: int) -> List[proto.Artifact]: + return self.get_artifacts_by_id([artifact_id]) \ No newline at end of file diff --git a/test/robot/MRandLogicalModel.robot b/test/robot/MRandLogicalModel.robot index dbb45239..61f527c1 100644 --- a/test/robot/MRandLogicalModel.robot +++ b/test/robot/MRandLogicalModel.robot @@ -1,15 +1,12 @@ *** Settings *** Library String -Resource MRviaREST.resource +Resource MRkeywords.resource Library MLMetadata.py *** Comments *** -You can replace the underlying keyword definition to go via: -- REST entrypoint -- Python entrypoint -for example by changing the imported `Resource MRviaREST.resource` -with an alternative implementation, etc. +You can switch between REST and Python flow by environment variables, +as documented in the keyword implementation *** Test Cases *** @@ -29,15 +26,13 @@ Verify basic logical mapping between MR and MLMD ${aId} Convert To Integer ${aId} # RegisteredModel shall result in a MLMD Context - @{singList} Create List ${rId} - ${mlmdProto} Get Contexts By Id ${singList} + ${mlmdProto} Get Contexts By Single Id ${rId} Log To Console ${mlmdProto[0]} Should be equal ${mlmdProto[0].type} odh.RegisteredModel Should be equal ${mlmdProto[0].name} ${name} # ModelVersion shall result in a MLMD Context and parent Context(of RegisteredModel) - @{singList} Create List ${vId} - ${mlmdProto} Get Contexts By Id ${singList} + ${mlmdProto} Get Contexts By Single Id ${vId} Log To Console ${mlmdProto[0]} Should be equal ${mlmdProto[0].type} odh.ModelVersion Should be equal ${mlmdProto[0].name} ${rId}:v1 @@ -46,8 +41,7 @@ Verify basic logical mapping between MR and MLMD # ModelArtifact shall result in a MLMD Artifact and Attribution(to the parent Context of ModelVersion) ${aNamePrefix} Set Variable ${vId}: - @{singList} Create List ${aId} - ${mlmdProto} Get Artifacts By Id ${singList} + ${mlmdProto} Get Artifacts By Single Id ${aId} Log To Console ${mlmdProto[0]} Should be equal ${mlmdProto[0].type} odh.ModelArtifact Should Start With ${mlmdProto[0].name} ${aNamePrefix} diff --git a/test/robot/MRkeywords.resource b/test/robot/MRkeywords.resource new file mode 100644 index 00000000..94387c15 --- /dev/null +++ b/test/robot/MRkeywords.resource @@ -0,0 +1,131 @@ +*** Settings *** +Library RequestsLibrary +Library Collections +Library String +Library ModelRegistry.py + +*** Variables *** +${MR_HOST} %{TEST_MR_HOST=localhost} +${MODE} %{TEST_MODE=REST} + +*** Keywords *** +I create a RegisteredModel having + [Arguments] ${name} + IF $MODE == "REST" + ${data} Create Dictionary name=${name} + ${resp} POST url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/registered_models json=${data} expected_status=201 + Log to console ${resp.json()} + ${result} Set Variable ${resp.json()['id']} + ELSE + ${data} Create Dictionary name=${name} + ${result} Upsert Registered Model ${data} + Log to console ${result} + END + [return] ${result} + + +I create a RegisteredModel + [Arguments] ${payload} + IF $MODE == "REST" + ${resp} POST url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/registered_models json=&{payload} expected_status=201 + Log to console ${resp.json()} + ${result} Set Variable ${resp.json()['id']} + ELSE + Fail Not Implemented + END + [return] ${result} + + +I create a child ModelVersion having + [Arguments] ${registeredModelID} ${name} + IF $MODE == "REST" + ${data}= Create Dictionary name=${name} registeredModelID=${registeredModelID} + ${resp}= POST url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_versions json=${data} expected_status=201 + Log to console ${resp.json()} + ${result} Set Variable ${resp.json()['id']} + ELSE + ${data} Create Dictionary name=${name} + ${result} Upsert Model Version ${data} ${registeredModelID} + Log to console ${result} + END + [return] ${result} + + +I create a child ModelVersion + [Arguments] ${registeredModelID} ${payload} + IF $MODE == "REST" + Set To Dictionary ${payload} registeredModelID=${registeredModelID} + ${resp}= POST url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_versions json=&{payload} expected_status=201 + Log to console ${resp.json()} + ${result} Set Variable ${resp.json()['id']} + ELSE + Fail Not Implemented + END + [return] ${result} + + +I create a child ModelArtifact having + [Arguments] ${modelversionId} ${uri} + IF $MODE == "REST" + ${data}= Create Dictionary uri=${uri} artifactType=model-artifact + Log to console ${data} + ${resp}= POST url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_versions/${modelversionId}/artifacts json=${data} expected_status=201 + Log to console ${resp.json()} + ${result} Set Variable ${resp.json()['id']} + ELSE + ${data} Create Dictionary uri=${uri} + ${result} Upsert Model Artifact ${data} ${modelversionId} + Log to console ${result} + END + [return] ${result} + + +I create a child ModelArtifact + [Arguments] ${modelversionId} ${payload} + IF $MODE == "REST" + ${resp}= POST url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_versions/${modelversionId}/artifacts json=&{payload} expected_status=201 + Log to console ${resp.json()} + ${result} Set Variable ${resp.json()['id']} + ELSE + Fail Not Implemented + END + [return] ${result} + + +I get RegisteredModelByID + [Arguments] ${id} + IF $MODE == "REST" + ${resp}= GET url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/registered_models/${id} expected_status=200 + ${result} Set Variable ${resp.json()} + Log to console ${resp.json()} + ELSE + Log to console ${MODE} + Fail Not Implemented + END + [return] ${result} + + +I get ModelVersionByID + [Arguments] ${id} + IF $MODE == "REST" + ${resp}= GET url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_versions/${id} expected_status=200 + ${result} Set Variable ${resp.json()} + Log to console ${resp.json()} + ELSE + Log to console ${MODE} + Fail Not Implemented + END + [return] ${result} + + +I get ModelArtifactByID + [Arguments] ${id} + IF $MODE == "REST" + ${resp}= GET url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_artifacts/${id} expected_status=200 + ${result} Set Variable ${resp.json()} + Log to console ${resp.json()} + ELSE + Log to console ${MODE} + Fail Not Implemented + END + [return] ${result} diff --git a/test/robot/MRviaPython.resource b/test/robot/MRviaPython.resource deleted file mode 100644 index 54bb5b58..00000000 --- a/test/robot/MRviaPython.resource +++ /dev/null @@ -1,17 +0,0 @@ -*** Keywords *** -I create a RegisteredModel having - [Arguments] ${name} - # TODO: implement keyword "I create a RegisteredModel having". - Fail Not Implemented - - -I create a child ModelVersion having - [Arguments] ${registeredModelID} ${name} - # TODO: implement keyword "I create a child ModelVersion having". - Fail Not Implemented - - -I create a child ModelArtifact having - [Arguments] ${modelversionId} ${uri} - # TODO: implement keyword "I create a child ModelArtifact having". - Fail Not Implemented diff --git a/test/robot/MRviaREST.resource b/test/robot/MRviaREST.resource deleted file mode 100644 index 8b2d1cfa..00000000 --- a/test/robot/MRviaREST.resource +++ /dev/null @@ -1,52 +0,0 @@ -*** Settings *** -Library RequestsLibrary -Library String - -*** Variables *** -${mr_host} localhost - -*** Keywords *** -I create a RegisteredModel having - [Arguments] ${name} - ${data}= Create Dictionary name=${name} - ${resp}= POST url=http://${mr_host}:8080/api/model_registry/v1alpha1/registered_models json=${data} expected_status=201 - Log to console ${resp.json()} - [return] ${resp.json()["id"]} - - -I create a child ModelVersion having - [Arguments] ${registeredModelID} ${name} - ${data}= Create Dictionary name=${name} registeredModelID=${registeredModelID} - ${resp}= POST url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_versions json=${data} expected_status=201 - Log to console ${resp.json()} - [return] ${resp.json()["id"]} - -I create a child ModelArtifact having - [Arguments] ${modelversionId} ${uri} - ${data}= Create Dictionary uri=${uri} artifactType=model-artifact - Log to console ${data} - ${resp}= POST url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_versions/${modelversionId}/artifacts json=${data} expected_status=201 - Log to console ${resp.json()} - [return] ${resp.json()["id"]} - - -I get RegisteredModelByID - [Arguments] ${id} - ${resp}= GET url=http://${mr_host}:8080/api/model_registry/v1alpha1/registered_models/${id} expected_status=200 - Log to console ${resp.json()} - [return] ${resp.json()} - - -I get ModelVersionByID - [Arguments] ${id} - ${resp}= GET url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_versions/${id} expected_status=200 - Log to console ${resp.json()} - [return] ${resp.json()} - - -I get ModelArtifactByID - [Arguments] ${id} - ${resp}= GET url=http://${mr_host}:8080/api/model_registry/v1alpha1/model_artifacts/${id} expected_status=200 - Log to console ${resp.json()} - [return] ${resp.json()} - diff --git a/test/robot/ModelRegistry.py b/test/robot/ModelRegistry.py new file mode 100644 index 00000000..2e594e68 --- /dev/null +++ b/test/robot/ModelRegistry.py @@ -0,0 +1,41 @@ +import model_registry as mr +from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel +from robot.libraries.BuiltIn import BuiltIn + +def write_to_console(s): + print(s) + BuiltIn().log_to_console(s) + + +class ModelRegistry(mr.client.ModelRegistry): + def __init__(self, host: str = 'localhost', port: int = 9090): + super().__init__(host, port) + + def upsert_registered_model(self, registered_model) -> str: + p = RegisteredModel(None) + for key, value in registered_model.items(): + setattr(p, key, value) + return super().upsert_registered_model(p) + + def upsert_model_version(self, model_version, registered_model_id: str) -> str: + write_to_console(model_version) + p = ModelVersion(ModelArtifact("", ""), "", "") + for key, value in model_version.items(): + setattr(p, key, value) + write_to_console(p) + return super().upsert_model_version(p, registered_model_id) + + def upsert_model_artifact(self, model_artifact, model_version_id: str) -> str: + write_to_console(model_artifact) + p = ModelArtifact(None, None) + for key, value in model_artifact.items(): + setattr(p, key, value) + write_to_console(p) + return super().upsert_model_artifact(p, model_version_id) + + +# Used only for quick smoke tests +if __name__ == "__main__": + demo_instance = ModelRegistry() + demo_instance.upsert_registered_model({'name': 'asd11'}) + demo_instance.upsert_model_version({'name': 'v1'}, None) diff --git a/test/robot/UserStory.robot b/test/robot/UserStory.robot index 40606145..34f38864 100644 --- a/test/robot/UserStory.robot +++ b/test/robot/UserStory.robot @@ -1,5 +1,9 @@ *** Settings *** -Resource MRviaREST.resource +Library yaml +Library OperatingSystem +Library Collections +Resource MRkeywords.resource +Test Setup Test Setup with dummy data *** Comments *** @@ -8,13 +12,48 @@ These User Story(-ies) are defined in the PM document *** Test Cases *** As a MLOps engineer I would like to store Model name - ${name}= Generate Random String 8 [LETTERS] - ${rId}= Given I create a RegisteredModel having name=${name} - ${vId}= And I create a child ModelVersion having registeredModelID=${rId} name=v1 - ${aId}= And I create a child ModelArtifact having modelversionId=${vId} uri=s3://12345 - ${r}= Then I get RegisteredModelByID id=${rId} - And Should be equal ${r["name"]} ${name} - ${r}= Then I get ModelVersionByID id=${vId} - And Should be equal ${r["name"]} v1 - ${r}= Then I get ModelArtifactByID id=${aId} - And Should be equal ${r["uri"]} s3://12345 + ${rId} Given I create a RegisteredModel having name=${name} + ${vId} And I create a child ModelVersion having registeredModelID=${rId} name=v1 + ${aId} And I create a child ModelArtifact having modelversionId=${vId} uri=s3://12345 + ${r} Then I get RegisteredModelByID id=${rId} + And Should be equal ${r["name"]} ${name} + ${r} Then I get ModelVersionByID id=${vId} + And Should be equal ${r["name"]} v1 + ${r} Then I get ModelArtifactByID id=${aId} + And Should be equal ${r["uri"]} s3://12345 + +As a MLOps engineer I would like to store a description of the model + Set To Dictionary ${registered_model} description=Lorem ipsum dolor sit amet name=${name} + Set To Dictionary ${model_version} description=consectetur adipiscing elit + Set To Dictionary ${model_artifact} description=sed do eiusmod tempor incididunt + ${rId} Given I create a RegisteredModel payload=${registered_model} + ${vId} And I create a child ModelVersion registeredModelID=${rId} payload=&{model_version} + ${aId} And I create a child ModelArtifact modelversionId=${vId} payload=&{model_artifact} + ${r} Then I get RegisteredModelByID id=${rId} + And Should be equal ${r["description"]} Lorem ipsum dolor sit amet + ${r} Then I get ModelVersionByID id=${vId} + And Should be equal ${r["description"]} consectetur adipiscing elit + ${r} Then I get ModelArtifactByID id=${aId} + And Should be equal ${r["description"]} sed do eiusmod tempor incididunt + + +*** Keywords *** +Test Setup with dummy data + Log To Console TEST SETUP + ${name} Generate Random String 8 [LETTERS] + Set Test Variable $name ${name} + ${YAML} Get File ${CURDIR}${/}data.yaml + ${YAML} yaml.Safe Load ${YAML} + &{registered_model} Get From Dictionary ${YAML} registered_model + Set Test Variable ®istered_model &{registered_model} + &{model_version} Get From Dictionary ${YAML} model_version + Set Test Variable &model_version &{model_version} + &{model_artifact} Get From Dictionary ${YAML} model_artifact + Set Test Variable &model_artifact &{model_artifact} + + +*** Variables *** +&{registered_model} +&{model_version} +&{model_artifact} +${name} \ No newline at end of file diff --git a/test/robot/data.yaml b/test/robot/data.yaml new file mode 100644 index 00000000..3de590e7 --- /dev/null +++ b/test/robot/data.yaml @@ -0,0 +1,9 @@ +# dummy data for Robot Framework tests +registered_model: + name: RegisteredModelName +model_version: + name: v1.2.3 +model_artifact: + artifactType: model-artifact + name: ModelArtifactName + uri: s3://12345 From de3c5f1fa14f26e813e79ff550c4a1fca489fb28 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Thu, 16 Nov 2023 10:17:42 +0000 Subject: [PATCH 145/254] Align prefix behaviour in Python for ModelArtifact Co-authored-by: Andrea Lamparelli --- clients/python/src/model_registry/client.py | 1 + clients/python/src/model_registry/types/artifacts.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 1226aa20..6a970303 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -319,6 +319,7 @@ def upsert_model_artifact( except StoreException as e: if "found" not in str(e).lower(): raise + model_artifact._model_version_id = model_version_id proto_ma = self._map(model_artifact) id = self._store.put_artifact(proto_ma) self._store.put_attribution(mv_id, id) diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index 76358483..ec349922 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -93,9 +93,14 @@ class ModelArtifact(BaseArtifact, Prefixable): storage_path: Optional[str] = field(kw_only=True, default=None) service_account_name: Optional[str] = field(kw_only=True, default=None) + _model_version_id: Optional[str] = field(init=False, default=None) + @property def mlmd_name_prefix(self) -> str: - return uuid4().hex + if self._model_version_id: + return self._model_version_id + else: + return uuid4().hex def map(self) -> Artifact: mlmd_obj = super().map() From a499a19769706ac0551b63861a9655857ec9a4cb Mon Sep 17 00:00:00 2001 From: tarilabs Date: Thu, 16 Nov 2023 10:23:33 +0000 Subject: [PATCH 146/254] Simplify accessory MLMD functions --- test/robot/MLMetadata.py | 8 ++++---- test/robot/MRandLogicalModel.robot | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/test/robot/MLMetadata.py b/test/robot/MLMetadata.py index 0d2ccc28..5021fdef 100644 --- a/test/robot/MLMetadata.py +++ b/test/robot/MLMetadata.py @@ -12,8 +12,8 @@ def __init__(self, host: str = 'localhost', port: int = 9090): print(client_connection_config) super().__init__(client_connection_config) - def get_contexts_by_single_id(self, context_id: int) -> List[proto.Context]: - return self.get_contexts_by_id([context_id]) + def get_context_by_single_id(self, context_id: int) -> List[proto.Context]: + return self.get_contexts_by_id([context_id])[0] - def get_artifacts_by_single_id(self, artifact_id: int) -> List[proto.Artifact]: - return self.get_artifacts_by_id([artifact_id]) \ No newline at end of file + def get_artifact_by_single_id(self, artifact_id: int) -> List[proto.Artifact]: + return self.get_artifacts_by_id([artifact_id])[0] \ No newline at end of file diff --git a/test/robot/MRandLogicalModel.robot b/test/robot/MRandLogicalModel.robot index 61f527c1..277e9980 100644 --- a/test/robot/MRandLogicalModel.robot +++ b/test/robot/MRandLogicalModel.robot @@ -26,25 +26,25 @@ Verify basic logical mapping between MR and MLMD ${aId} Convert To Integer ${aId} # RegisteredModel shall result in a MLMD Context - ${mlmdProto} Get Contexts By Single Id ${rId} - Log To Console ${mlmdProto[0]} - Should be equal ${mlmdProto[0].type} odh.RegisteredModel - Should be equal ${mlmdProto[0].name} ${name} + ${mlmdProto} Get Context By Single Id ${rId} + Log To Console ${mlmdProto} + Should be equal ${mlmdProto.type} odh.RegisteredModel + Should be equal ${mlmdProto.name} ${name} # ModelVersion shall result in a MLMD Context and parent Context(of RegisteredModel) - ${mlmdProto} Get Contexts By Single Id ${vId} - Log To Console ${mlmdProto[0]} - Should be equal ${mlmdProto[0].type} odh.ModelVersion - Should be equal ${mlmdProto[0].name} ${rId}:v1 + ${mlmdProto} Get Context By Single Id ${vId} + Log To Console ${mlmdProto} + Should be equal ${mlmdProto.type} odh.ModelVersion + Should be equal ${mlmdProto.name} ${rId}:v1 ${mlmdProto} Get Parent Contexts By Context ${vId} Should be equal ${mlmdProto[0].id} ${rId} # ModelArtifact shall result in a MLMD Artifact and Attribution(to the parent Context of ModelVersion) ${aNamePrefix} Set Variable ${vId}: - ${mlmdProto} Get Artifacts By Single Id ${aId} - Log To Console ${mlmdProto[0]} - Should be equal ${mlmdProto[0].type} odh.ModelArtifact - Should Start With ${mlmdProto[0].name} ${aNamePrefix} - Should be equal ${mlmdProto[0].uri} s3://12345 + ${mlmdProto} Get Artifact By Single Id ${aId} + Log To Console ${mlmdProto} + Should be equal ${mlmdProto.type} odh.ModelArtifact + Should Start With ${mlmdProto.name} ${aNamePrefix} + Should be equal ${mlmdProto.uri} s3://12345 ${mlmdProto} Get Artifacts By Context ${vId} Should be equal ${mlmdProto[0].id} ${aId} From 5dedce97f8bc0ba756e3c0e455d89e95d40e84c0 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Thu, 16 Nov 2023 10:25:49 +0000 Subject: [PATCH 147/254] Align default also for Go proxy cmd --- cmd/proxy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/proxy.go b/cmd/proxy.go index aafd87b9..e9dea571 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -79,5 +79,5 @@ type ProxyConfig struct { var proxyCfg = ProxyConfig{ MLMDHostname: "localhost", - MLMDPort: 8081, + MLMDPort: 9090, } From c9e0753f2ead3e65c0d5c19cd00a25d848039bf0 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Thu, 16 Nov 2023 10:52:58 +0000 Subject: [PATCH 148/254] Test description property and refactors --- test/robot/MRandLogicalModel.robot | 43 ++++++++++++++++++++++++------ test/robot/MRkeywords.resource | 9 ++++--- test/robot/Setup.resource | 26 ++++++++++++++++++ test/robot/UserStory.robot | 26 +----------------- 4 files changed, 68 insertions(+), 36 deletions(-) create mode 100644 test/robot/Setup.resource diff --git a/test/robot/MRandLogicalModel.robot b/test/robot/MRandLogicalModel.robot index 277e9980..5873b7a2 100644 --- a/test/robot/MRandLogicalModel.robot +++ b/test/robot/MRandLogicalModel.robot @@ -1,7 +1,9 @@ *** Settings *** -Library String -Resource MRkeywords.resource Library MLMetadata.py +Library Collections +Resource Setup.resource +Resource MRkeywords.resource +Test Setup Test Setup with dummy data *** Comments *** @@ -17,12 +19,11 @@ Verify basic logical mapping between MR and MLMD ... ModelVersion shall result in a MLMD Context and parent Context(of RegisteredModel) ... ModelArtifact shall result in a MLMD Artifact and Attribution(to the parent Context of ModelVersion) - ${name}= Generate Random String 8 [LETTERS] - ${rId}= Given I create a RegisteredModel having name=${name} - ${vId}= And I create a child ModelVersion having registeredModelID=${rId} name=v1 - ${aId}= And I create a child ModelArtifact having modelversionId=${vId} uri=s3://12345 - ${rId}= Convert To Integer ${rId} - ${vId}= Convert To Integer ${vId} + ${rId} Given I create a RegisteredModel having name=${name} + ${vId} And I create a child ModelVersion having registeredModelID=${rId} name=v1 + ${aId} And I create a child ModelArtifact having modelversionId=${vId} uri=s3://12345 + ${rId} Convert To Integer ${rId} + ${vId} Convert To Integer ${vId} ${aId} Convert To Integer ${aId} # RegisteredModel shall result in a MLMD Context @@ -48,3 +49,29 @@ Verify basic logical mapping between MR and MLMD Should be equal ${mlmdProto.uri} s3://12345 ${mlmdProto} Get Artifacts By Context ${vId} Should be equal ${mlmdProto[0].id} ${aId} + +Verify logical mapping of description property between MR and MLMD + Comment This test ensures logical mapping of the description bewteen MR entities and MLMD entities + ... being implemented as a custom_property + + Set To Dictionary ${registered_model} description=Lorem ipsum dolor sit amet name=${name} + Set To Dictionary ${model_version} description=consectetur adipiscing elit + Set To Dictionary ${model_artifact} description=sed do eiusmod tempor incididunt + ${rId} Given I create a RegisteredModel payload=${registered_model} + ${vId} And I create a child ModelVersion registeredModelID=${rId} payload=&{model_version} + ${aId} And I create a child ModelArtifact modelversionId=${vId} payload=&{model_artifact} + ${rId} Convert To Integer ${rId} + ${vId} Convert To Integer ${vId} + ${aId} Convert To Integer ${aId} + + # RegisteredModel description + ${mlmdProto} Get Context By Single Id ${rId} + Should be equal ${mlmdProto.properties['description'].string_value} Lorem ipsum dolor sit amet + + # ModelVersion description + ${mlmdProto} Get Context By Single Id ${vId} + Should be equal ${mlmdProto.properties['description'].string_value} consectetur adipiscing elit + + # ModelArtifact description + ${mlmdProto} Get Artifact By Single Id ${aId} + Should be equal ${mlmdProto.properties['description'].string_value} sed do eiusmod tempor incididunt diff --git a/test/robot/MRkeywords.resource b/test/robot/MRkeywords.resource index 94387c15..7cd7f8cb 100644 --- a/test/robot/MRkeywords.resource +++ b/test/robot/MRkeywords.resource @@ -31,7 +31,8 @@ I create a RegisteredModel Log to console ${resp.json()} ${result} Set Variable ${resp.json()['id']} ELSE - Fail Not Implemented + ${result} Upsert Registered Model ${payload} + Log to console ${result} END [return] ${result} @@ -59,7 +60,8 @@ I create a child ModelVersion Log to console ${resp.json()} ${result} Set Variable ${resp.json()['id']} ELSE - Fail Not Implemented + ${result} Upsert Model Version ${payload} ${registeredModelID} + Log to console ${result} END [return] ${result} @@ -87,7 +89,8 @@ I create a child ModelArtifact Log to console ${resp.json()} ${result} Set Variable ${resp.json()['id']} ELSE - Fail Not Implemented + ${result} Upsert Model Artifact ${payload} ${modelversionId} + Log to console ${result} END [return] ${result} diff --git a/test/robot/Setup.resource b/test/robot/Setup.resource new file mode 100644 index 00000000..78d25b52 --- /dev/null +++ b/test/robot/Setup.resource @@ -0,0 +1,26 @@ +*** Settings *** +Library yaml +Library OperatingSystem +Library Collections +Library String + +*** Keywords *** +Test Setup with dummy data + Log To Console TEST SETUP + ${name} Generate Random String 8 [LETTERS] + Set Test Variable $name ${name} + ${YAML} Get File ${CURDIR}${/}data.yaml + ${YAML} yaml.Safe Load ${YAML} + &{registered_model} Get From Dictionary ${YAML} registered_model + Set Test Variable ®istered_model &{registered_model} + &{model_version} Get From Dictionary ${YAML} model_version + Set Test Variable &model_version &{model_version} + &{model_artifact} Get From Dictionary ${YAML} model_artifact + Set Test Variable &model_artifact &{model_artifact} + + +*** Variables *** +&{registered_model} +&{model_version} +&{model_artifact} +${name} \ No newline at end of file diff --git a/test/robot/UserStory.robot b/test/robot/UserStory.robot index 34f38864..4b9bad8b 100644 --- a/test/robot/UserStory.robot +++ b/test/robot/UserStory.robot @@ -1,7 +1,5 @@ *** Settings *** -Library yaml -Library OperatingSystem -Library Collections +Resource Setup.resource Resource MRkeywords.resource Test Setup Test Setup with dummy data @@ -35,25 +33,3 @@ As a MLOps engineer I would like to store a description of the model And Should be equal ${r["description"]} consectetur adipiscing elit ${r} Then I get ModelArtifactByID id=${aId} And Should be equal ${r["description"]} sed do eiusmod tempor incididunt - - -*** Keywords *** -Test Setup with dummy data - Log To Console TEST SETUP - ${name} Generate Random String 8 [LETTERS] - Set Test Variable $name ${name} - ${YAML} Get File ${CURDIR}${/}data.yaml - ${YAML} yaml.Safe Load ${YAML} - &{registered_model} Get From Dictionary ${YAML} registered_model - Set Test Variable ®istered_model &{registered_model} - &{model_version} Get From Dictionary ${YAML} model_version - Set Test Variable &model_version &{model_version} - &{model_artifact} Get From Dictionary ${YAML} model_artifact - Set Test Variable &model_artifact &{model_artifact} - - -*** Variables *** -&{registered_model} -&{model_version} -&{model_artifact} -${name} \ No newline at end of file From 33e088a2ae036118ca44583c91548e9a740cc42a Mon Sep 17 00:00:00 2001 From: tarilabs Date: Thu, 16 Nov 2023 11:57:18 +0100 Subject: [PATCH 149/254] Minor change of naming --- test/robot/ModelRegistry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/robot/ModelRegistry.py b/test/robot/ModelRegistry.py index 2e594e68..6036ae48 100644 --- a/test/robot/ModelRegistry.py +++ b/test/robot/ModelRegistry.py @@ -37,5 +37,5 @@ def upsert_model_artifact(self, model_artifact, model_version_id: str) -> str: # Used only for quick smoke tests if __name__ == "__main__": demo_instance = ModelRegistry() - demo_instance.upsert_registered_model({'name': 'asd11'}) + demo_instance.upsert_registered_model({'name': 'testing123'}) demo_instance.upsert_model_version({'name': 'v1'}, None) From 245c7dfcfb6d3357bee88d3560944bb57721d55f Mon Sep 17 00:00:00 2001 From: tarilabs Date: Mon, 20 Nov 2023 14:39:00 +0100 Subject: [PATCH 150/254] Add doc with diagram for Robot Framework role --- README.md | 18 +++- doc/Model Registry Testing areas.drawio | 105 ++++++++++++++++++++++++ doc/Model Registry Testing areas.png | Bin 0 -> 87193 bytes 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 doc/Model Registry Testing areas.drawio create mode 100644 doc/Model Registry Testing areas.png diff --git a/README.md b/README.md index 49e8ef2f..597ea6ac 100644 --- a/README.md +++ b/README.md @@ -108,4 +108,20 @@ docker compose -f docker-compose[-local].yaml up The main difference between the two docker compose files is that `-local` one build the model registry from source, the other one, instead, download the `latest` pushed [quay.io](https://quay.io/repository/opendatahub/model-registry?tab=tags) image. -When shutting down the docker compose, you might want to clean-up the SQLite db file generated by ML Metadata, for example `./test/config/ml-metadata/metadata.sqlite.db` \ No newline at end of file +When shutting down the docker compose, you might want to clean-up the SQLite db file generated by ML Metadata, for example `./test/config/ml-metadata/metadata.sqlite.db` + +### Testing architecture + +The following diagram illustrate testing strategy for the several components in Model Registry project: + +![](/doc/Model%20Registry%20Testing%20areas.png) + +Go layers components are tested with Unit Tests written in Go, as well as Integration Tests leveraging Testcontainers. +This allows to verify the expected "Core layer" of logical data mapping developed implemented in Go, matches technical expectations. + +Python client is also tested with Unit Tests and Integration Tests written in Python. + +End-to-end testing is developed with Robot Framework; this higher-lever layer of testing is used to: +- demonstrate *User Stories* from high level perspective +- demonstrate coherent logical data mapping by performing the same high level capabilities, using REST API flow Vs Python client flow, +directly checking the end results in the backend gRPC MLMD server. diff --git a/doc/Model Registry Testing areas.drawio b/doc/Model Registry Testing areas.drawio new file mode 100644 index 00000000..a9e9ce25 --- /dev/null +++ b/doc/Model Registry Testing areas.drawio @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/Model Registry Testing areas.png b/doc/Model Registry Testing areas.png new file mode 100644 index 0000000000000000000000000000000000000000..3ff9391f8cbca528eb030b9102b7343d3e29b5d8 GIT binary patch literal 87193 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 Date: Thu, 23 Nov 2023 09:45:24 +0100 Subject: [PATCH 151/254] Remove BDD with Godog, as now using RobotFramework (#162) --- go.mod | 7 - go.sum | 25 ---- test/bdd/conn_config.pb | 6 - test/bdd/features/example.feature | 9 -- test/bdd/mr_service_features_test.go | 209 --------------------------- 5 files changed, 256 deletions(-) delete mode 100644 test/bdd/conn_config.pb delete mode 100644 test/bdd/features/example.feature delete mode 100644 test/bdd/mr_service_features_test.go diff --git a/go.mod b/go.mod index 62acb005..ad85c9d7 100644 --- a/go.mod +++ b/go.mod @@ -17,13 +17,7 @@ require ( require ( github.com/containerd/log v0.1.0 // indirect - github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect - github.com/cucumber/messages/go/v21 v21.0.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/gofrs/uuid v4.3.1+incompatible // indirect - github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-memdb v1.3.4 // indirect - github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sagikazarmark/locafero v0.3.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect @@ -42,7 +36,6 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/containerd/containerd v1.7.7 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect - github.com/cucumber/godog v0.13.0 github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.7+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect diff --git a/go.sum b/go.sum index facef6ef..032d60d5 100644 --- a/go.sum +++ b/go.sum @@ -68,16 +68,8 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= -github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= -github.com/cucumber/godog v0.13.0 h1:KvX9kNWmAJwp882HmObGOyBbNUP5SXQ+SDLNajsuV7A= -github.com/cucumber/godog v0.13.0/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces= -github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= -github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= -github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -113,9 +105,6 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= -github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -183,18 +172,8 @@ github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= -github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= -github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -274,7 +253,6 @@ github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= -github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -291,8 +269,6 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= @@ -644,7 +620,6 @@ google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= diff --git a/test/bdd/conn_config.pb b/test/bdd/conn_config.pb deleted file mode 100644 index 774b7aa0..00000000 --- a/test/bdd/conn_config.pb +++ /dev/null @@ -1,6 +0,0 @@ -connection_config { - sqlite { - filename_uri: '/tmp/shared/metadata.sqlite.db' - connection_mode: READWRITE_OPENCREATE - } -} diff --git a/test/bdd/features/example.feature b/test/bdd/features/example.feature deleted file mode 100644 index 70049726..00000000 --- a/test/bdd/features/example.feature +++ /dev/null @@ -1,9 +0,0 @@ -Feature: As a MLOps engineer I would like the Model Registry to store metadata information about models - Taken from User Stories - - Scenario: As a MLOps engineer I would like to store Model name - Given I have a connection to MR - When I store a RegisteredModel with name "Pricing Model" and a child ModelVersion with name "v1" and a child Artifact with uri "s3://12345" - Then there should be a mlmd Context of type "odh.RegisteredModel" named "Pricing Model" - And there should be a mlmd Context of type "odh.ModelVersion" having property named "model_name" valorised with string value "Pricing Model" - diff --git a/test/bdd/mr_service_features_test.go b/test/bdd/mr_service_features_test.go deleted file mode 100644 index d4e45cd2..00000000 --- a/test/bdd/mr_service_features_test.go +++ /dev/null @@ -1,209 +0,0 @@ -package bdd_test - -import ( - "context" - "fmt" - "log" - "os" - "testing" - - "github.com/cucumber/godog" - "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" - "github.com/opendatahub-io/model-registry/pkg/api" - "github.com/opendatahub-io/model-registry/pkg/core" - "github.com/opendatahub-io/model-registry/pkg/openapi" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" -) - -const useProvider = testcontainers.ProviderDefault // or explicit to testcontainers.ProviderPodman if needed - -var ( - mlmdHostname string - mlmdPort int -) - -func TestFeatures(t *testing.T) { - suite := godog.TestSuite{ - ScenarioInitializer: InitializeScenario, - Options: &godog.Options{ - Format: "pretty", - Paths: []string{"features"}, - TestingT: t, // Testing instance that will run subtests. - }, - } - - if suite.Run() != 0 { - t.Fatal("non-zero status returned, failed to run feature tests") - } -} - -type wdCtxKey struct{} -type testContainerCtxKey struct{} -type svcLayerCtxKey struct{} -type connCtxKey struct{} - -func iHaveAConnectionToMR(ctx context.Context) (context.Context, error) { - mlmdAddr := fmt.Sprintf("%s:%d", mlmdHostname, mlmdPort) - conn, err := grpc.DialContext( - context.Background(), - mlmdAddr, - grpc.WithReturnConnectionError(), - grpc.WithBlock(), - grpc.WithTransportCredentials(insecure.NewCredentials()), - ) - if err != nil { - log.Fatalf("Error dialing connection to mlmd server %s: %v", mlmdAddr, err) - return nil, err - } - ctx = context.WithValue(ctx, connCtxKey{}, conn) - service, err := core.NewModelRegistryService(conn) - if err != nil { - log.Fatalf("Error creating core service: %v", err) - return nil, err - } - return context.WithValue(ctx, svcLayerCtxKey{}, service), nil -} - -func iStoreARegisteredModelWithNameAndAChildModelVersionWithNameAndAChildArtifactWithUri(ctx context.Context, registedModelName, modelVersionName, artifactURI string) error { - service, ok := ctx.Value(svcLayerCtxKey{}).(api.ModelRegistryApi) - if !ok { - return fmt.Errorf("not found service layer connection in godog context") - } - var registeredModel *openapi.RegisteredModel - var err error - registeredModel, err = service.UpsertRegisteredModel(&openapi.RegisteredModel{ - Name: ®istedModelName, - }) - if err != nil { - return err - } - - var modelVersion *openapi.ModelVersion - if modelVersion, err = service.UpsertModelVersion(&openapi.ModelVersion{Name: &modelVersionName}, registeredModel.Id); err != nil { - return err - } - - if _, err = service.UpsertModelArtifact(&openapi.ModelArtifact{Uri: &artifactURI}, modelVersion.Id); err != nil { - return err - } - - return nil -} - -func thereShouldBeAMlmdContextOfTypeNamed(ctx context.Context, arg1, arg2 string) error { - conn := ctx.Value(connCtxKey{}).(*grpc.ClientConn) - client := proto.NewMetadataStoreServiceClient(conn) - query := fmt.Sprintf("type = \"%s\" and name = \"%s\"", arg1, arg2) - fmt.Println("query: ", query) - resp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{ - Options: &proto.ListOperationOptions{ - FilterQuery: &query, - }, - }) - if err != nil { - return err - } - if len(resp.Contexts) != 1 { - return fmt.Errorf("Unexpected mlmd Context result size (%d), %v", len(resp.Contexts), resp.Contexts) - } - return nil -} - -func thereShouldBeAMlmdContextOfTypeHavingPropertyNamedValorisedWithStringValue(ctx context.Context, arg1, arg2, arg3 string) error { - conn := ctx.Value(connCtxKey{}).(*grpc.ClientConn) - client := proto.NewMetadataStoreServiceClient(conn) - query := fmt.Sprintf("type = \"%s\" and properties.%s.string_value = \"%s\"", arg1, arg2, arg3) - fmt.Println("query: ", query) - resp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{ - Options: &proto.ListOperationOptions{ - FilterQuery: &query, - }, - }) - if err != nil { - return err - } - if len(resp.Contexts) != 1 { - return fmt.Errorf("Unexpected mlmd Context result size (%d), %v", len(resp.Contexts), resp.Contexts) - } - return nil -} - -func InitializeScenario(ctx *godog.ScenarioContext) { - ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) { - wd, mlmdgrpc, err := setupTestContainer(ctx) - if err != nil { - return ctx, err - } - ctx = context.WithValue(ctx, wdCtxKey{}, wd) - ctx = context.WithValue(ctx, testContainerCtxKey{}, mlmdgrpc) - mappedHost, err := mlmdgrpc.Host(ctx) - if err != nil { - return ctx, err - } - mappedPort, err := mlmdgrpc.MappedPort(ctx, "8080") - if err != nil { - return ctx, err - } - // TODO: these are effectively global in main and could be worthy to revisit - mlmdHostname = mappedHost - mlmdPort = mappedPort.Int() - return ctx, nil - }) - ctx.Step(`^I have a connection to MR$`, iHaveAConnectionToMR) - ctx.Step(`^I store a RegisteredModel with name "([^"]*)" and a child ModelVersion with name "([^"]*)" and a child Artifact with uri "([^"]*)"$`, iStoreARegisteredModelWithNameAndAChildModelVersionWithNameAndAChildArtifactWithUri) - ctx.Step(`^there should be a mlmd Context of type "([^"]*)" named "([^"]*)"$`, thereShouldBeAMlmdContextOfTypeNamed) - ctx.Step(`^there should be a mlmd Context of type "([^"]*)" having property named "([^"]*)" valorised with string value "([^"]*)"$`, thereShouldBeAMlmdContextOfTypeHavingPropertyNamedValorisedWithStringValue) - ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) { - conn := ctx.Value(connCtxKey{}).(*grpc.ClientConn) - conn.Close() - mlmdgrpc := ctx.Value(testContainerCtxKey{}).(testcontainers.Container) - if err := mlmdgrpc.Terminate(ctx); err != nil { - return ctx, err - } - wd := ctx.Value(wdCtxKey{}).(string) - _ = clearMetadataSqliteDB(wd) - return ctx, nil - }) -} - -func clearMetadataSqliteDB(wd string) error { - if err := os.Remove(fmt.Sprintf("%s/%s", wd, "metadata.sqlite.db")); err != nil { - return fmt.Errorf("Expected to clear sqlite file but didn't find: %v", err) - } - return nil -} - -func setupTestContainer(ctx context.Context) (string, testcontainers.Container, error) { - wd, err := os.Getwd() - if err != nil { - return "", nil, err - } - req := testcontainers.ContainerRequest{ - Image: "gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0", - ExposedPorts: []string{"8080/tcp"}, - Env: map[string]string{ - "METADATA_STORE_SERVER_CONFIG_FILE": "/tmp/shared/conn_config.pb", - }, - Mounts: testcontainers.ContainerMounts{ - testcontainers.ContainerMount{ - Source: testcontainers.GenericBindMountSource{ - HostPath: wd, - }, - Target: "/tmp/shared", - }, - }, - WaitingFor: wait.ForLog("Server listening on"), - } - mlmdgrpc, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ProviderType: useProvider, - ContainerRequest: req, - Started: true, - }) - if err != nil { - return "", nil, err - } - return wd, mlmdgrpc, nil -} From e0f29251df1f79dd6915ee93950c02aa96dff55b Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 23 Nov 2023 02:04:25 -0800 Subject: [PATCH 152/254] Add state properties for RegisteredModel, ModelVersion, and InferenceService (#185) * Add state properties for RegisteredModel, ModelVersion, and InferenceService. Fixes #184 * Add property state to mlmd types * Add openapi to mlmd mapping for states --------- Co-authored-by: Andrea Lamparelli --- api/openapi/model-registry.yaml | 41 +++++++ .../generated/mlmd_openapi_converter.gen.go | 3 + .../generated/openapi_converter.gen.go | 36 ++++++ .../converter/mlmd_converter_util_test.go | 48 ++++++++ internal/converter/mlmd_openapi_converter.go | 3 + .../converter/mlmd_openapi_converter_util.go | 39 +++++++ .../converter/openapi_mlmd_converter_util.go | 25 ++++ pkg/core/core.go | 3 + pkg/core/core_test.go | 36 ++++-- pkg/openapi/.openapi-generator/FILES | 3 + pkg/openapi/model_inference_service.go | 42 ++++++- pkg/openapi/model_inference_service_create.go | 42 ++++++- pkg/openapi/model_inference_service_state.go | 110 ++++++++++++++++++ pkg/openapi/model_inference_service_update.go | 42 ++++++- pkg/openapi/model_model_version.go | 42 ++++++- pkg/openapi/model_model_version_create.go | 42 ++++++- pkg/openapi/model_model_version_state.go | 110 ++++++++++++++++++ pkg/openapi/model_model_version_update.go | 42 ++++++- pkg/openapi/model_registered_model.go | 42 ++++++- pkg/openapi/model_registered_model_create.go | 42 ++++++- pkg/openapi/model_registered_model_state.go | 110 ++++++++++++++++++ pkg/openapi/model_registered_model_update.go | 42 ++++++- 22 files changed, 927 insertions(+), 18 deletions(-) create mode 100644 pkg/openapi/model_inference_service_state.go create mode 100644 pkg/openapi/model_model_version_state.go create mode 100644 pkg/openapi/model_registered_model_state.go diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index 0f3e2277..3d667975 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -1017,6 +1017,35 @@ components: - ABANDONED - REFERENCE type: string + RegisteredModelState: + description: |- + - LIVE: A state indicating that the `RegisteredModel` exists + - ARCHIVED: A state indicating that the `RegisteredModel` has been archived. + default: LIVE + enum: + - LIVE + - ARCHIVED + type: string + ModelVersionState: + description: |- + - LIVE: A state indicating that the `ModelVersion` exists + - ARCHIVED: A state indicating that the `ModelVersion` has been archived. + default: LIVE + enum: + - LIVE + - ARCHIVED + type: string + InferenceServiceState: + description: |- + - DEPLOYED: A state indicating that the `InferenceService` should be deployed. + - UNDEPLOYED: A state indicating that the `InferenceService` should be un-deployed. + The state indicates the desired state of inference service. + See the associated `ServeModel` for the actual status of service deployment action. + default: DEPLOYED + enum: + - DEPLOYED + - UNDEPLOYED + type: string ExecutionState: description: |- The state of the Execution. The state transitions are @@ -1103,6 +1132,11 @@ components: allOf: - $ref: '#/components/schemas/BaseResourceUpdate' + - + type: object + properties: + state: + $ref: '#/components/schemas/RegisteredModelState' ModelVersion: description: Represents a ModelVersion belonging to a RegisteredModel. allOf: @@ -1128,6 +1162,11 @@ components: allOf: - $ref: '#/components/schemas/BaseResourceUpdate' + - + type: object + properties: + state: + $ref: '#/components/schemas/ModelVersionState' BaseArtifactCreate: allOf: - @@ -1534,6 +1573,8 @@ components: runtime: description: Model runtime. type: string + state: + $ref: '#/components/schemas/InferenceServiceState' InferenceServiceCreate: description: >- An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index 7eaa270a..2b110d4b 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -33,6 +33,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertInferenceService(source *proto.Conte openapiInferenceService.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) openapiInferenceService.ModelVersionId = converter.MapPropertyModelVersionId((*source).Properties) openapiInferenceService.Runtime = converter.MapPropertyRuntime((*source).Properties) + openapiInferenceService.State = converter.MapInferenceServiceState(source) openapiInferenceService.RegisteredModelId = converter.MapPropertyRegisteredModelId((*source).Properties) openapiInferenceService.ServingEnvironmentId = converter.MapPropertyServingEnvironmentId((*source).Properties) pOpenapiInferenceService = &openapiInferenceService @@ -97,6 +98,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertModelVersion(source *proto.Context) } openapiModelVersion.ExternalID = pString openapiModelVersion.Name = converter.MapNameFromOwned((*source).Name) + openapiModelVersion.State = converter.MapModelVersionState(source) openapiModelVersion.Id = converter.Int64ToString((*source).Id) openapiModelVersion.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) openapiModelVersion.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) @@ -129,6 +131,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertRegisteredModel(source *proto.Contex openapiRegisteredModel.Id = converter.Int64ToString((*source).Id) openapiRegisteredModel.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) openapiRegisteredModel.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + openapiRegisteredModel.State = converter.MapRegisteredModelState(source) pOpenapiRegisteredModel = &openapiRegisteredModel } return pOpenapiRegisteredModel, nil diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index accd966d..8f98e9b4 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -49,6 +49,12 @@ func (c *OpenAPIConverterImpl) ConvertInferenceServiceCreate(source *openapi.Inf pString5 = &xstring5 } openapiInferenceService.Runtime = pString5 + var pOpenapiInferenceServiceState *openapi.InferenceServiceState + if (*source).State != nil { + openapiInferenceServiceState := openapi.InferenceServiceState(*(*source).State) + pOpenapiInferenceServiceState = &openapiInferenceServiceState + } + openapiInferenceService.State = pOpenapiInferenceServiceState openapiInferenceService.RegisteredModelId = (*source).RegisteredModelId openapiInferenceService.ServingEnvironmentId = (*source).ServingEnvironmentId pOpenapiInferenceService = &openapiInferenceService @@ -92,6 +98,12 @@ func (c *OpenAPIConverterImpl) ConvertInferenceServiceUpdate(source *openapi.Inf pString4 = &xstring4 } openapiInferenceService.Runtime = pString4 + var pOpenapiInferenceServiceState *openapi.InferenceServiceState + if (*source).State != nil { + openapiInferenceServiceState := openapi.InferenceServiceState(*(*source).State) + pOpenapiInferenceServiceState = &openapiInferenceServiceState + } + openapiInferenceService.State = pOpenapiInferenceServiceState pOpenapiInferenceService = &openapiInferenceService } return pOpenapiInferenceService, nil @@ -275,6 +287,12 @@ func (c *OpenAPIConverterImpl) ConvertModelVersionCreate(source *openapi.ModelVe pString3 = &xstring3 } openapiModelVersion.Name = pString3 + var pOpenapiModelVersionState *openapi.ModelVersionState + if (*source).State != nil { + openapiModelVersionState := openapi.ModelVersionState(*(*source).State) + pOpenapiModelVersionState = &openapiModelVersionState + } + openapiModelVersion.State = pOpenapiModelVersionState pOpenapiModelVersion = &openapiModelVersion } return pOpenapiModelVersion, nil @@ -304,6 +322,12 @@ func (c *OpenAPIConverterImpl) ConvertModelVersionUpdate(source *openapi.ModelVe pString2 = &xstring2 } openapiModelVersion.ExternalID = pString2 + var pOpenapiModelVersionState *openapi.ModelVersionState + if (*source).State != nil { + openapiModelVersionState := openapi.ModelVersionState(*(*source).State) + pOpenapiModelVersionState = &openapiModelVersionState + } + openapiModelVersion.State = pOpenapiModelVersionState pOpenapiModelVersion = &openapiModelVersion } return pOpenapiModelVersion, nil @@ -339,6 +363,12 @@ func (c *OpenAPIConverterImpl) ConvertRegisteredModelCreate(source *openapi.Regi pString3 = &xstring3 } openapiRegisteredModel.Name = pString3 + var pOpenapiRegisteredModelState *openapi.RegisteredModelState + if (*source).State != nil { + openapiRegisteredModelState := openapi.RegisteredModelState(*(*source).State) + pOpenapiRegisteredModelState = &openapiRegisteredModelState + } + openapiRegisteredModel.State = pOpenapiRegisteredModelState pOpenapiRegisteredModel = &openapiRegisteredModel } return pOpenapiRegisteredModel, nil @@ -368,6 +398,12 @@ func (c *OpenAPIConverterImpl) ConvertRegisteredModelUpdate(source *openapi.Regi pString2 = &xstring2 } openapiRegisteredModel.ExternalID = pString2 + var pOpenapiRegisteredModelState *openapi.RegisteredModelState + if (*source).State != nil { + openapiRegisteredModelState := openapi.RegisteredModelState(*(*source).State) + pOpenapiRegisteredModelState = &openapiRegisteredModelState + } + openapiRegisteredModel.State = pOpenapiRegisteredModelState pOpenapiRegisteredModel = &openapiRegisteredModel } return pOpenapiRegisteredModel, nil diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index 74b5d0b5..72a50b5b 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -538,6 +538,54 @@ func TestMapMLMDModelArtifactState(t *testing.T) { assertion.Nil(artifactState) } +func TestMapRegisteredModelState(t *testing.T) { + assertion := setup(t) + + state := MapRegisteredModelState(&proto.Context{Properties: map[string]*proto.Value{ + "state": {Value: &proto.Value_StringValue{StringValue: string(openapi.REGISTEREDMODELSTATE_LIVE)}}, + }}) + assertion.NotNil(state) + assertion.Equal(openapi.REGISTEREDMODELSTATE_LIVE, *state) + + state = MapRegisteredModelState(&proto.Context{Properties: map[string]*proto.Value{}}) + assertion.Nil(state) + + state = MapRegisteredModelState(nil) + assertion.Nil(state) +} + +func TestMapModelVersionState(t *testing.T) { + assertion := setup(t) + + state := MapModelVersionState(&proto.Context{Properties: map[string]*proto.Value{ + "state": {Value: &proto.Value_StringValue{StringValue: string(openapi.MODELVERSIONSTATE_LIVE)}}, + }}) + assertion.NotNil(state) + assertion.Equal(openapi.MODELVERSIONSTATE_LIVE, *state) + + state = MapModelVersionState(&proto.Context{Properties: map[string]*proto.Value{}}) + assertion.Nil(state) + + state = MapModelVersionState(nil) + assertion.Nil(state) +} + +func TestMapInferenceServiceState(t *testing.T) { + assertion := setup(t) + + state := MapInferenceServiceState(&proto.Context{Properties: map[string]*proto.Value{ + "state": {Value: &proto.Value_StringValue{StringValue: string(openapi.INFERENCESERVICESTATE_DEPLOYED)}}, + }}) + assertion.NotNil(state) + assertion.Equal(openapi.INFERENCESERVICESTATE_DEPLOYED, *state) + + state = MapInferenceServiceState(&proto.Context{Properties: map[string]*proto.Value{}}) + assertion.Nil(state) + + state = MapInferenceServiceState(nil) + assertion.Nil(state) +} + func TestMapServingEnvironmentType(t *testing.T) { assertion := setup(t) diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index 8d28c3a2..be7d2b46 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -15,10 +15,12 @@ import ( // goverter:extend MapMLMDCustomProperties type MLMDToOpenAPIConverter interface { // goverter:map Properties Description | MapDescription + // goverter:map . State | MapRegisteredModelState ConvertRegisteredModel(source *proto.Context) (*openapi.RegisteredModel, error) // goverter:map Name | MapNameFromOwned // goverter:map Properties Description | MapDescription + // goverter:map . State | MapModelVersionState ConvertModelVersion(source *proto.Context) (*openapi.ModelVersion, error) // goverter:map Name | MapNameFromOwned @@ -42,6 +44,7 @@ type MLMDToOpenAPIConverter interface { // goverter:map Properties ModelVersionId | MapPropertyModelVersionId // goverter:map Properties RegisteredModelId | MapPropertyRegisteredModelId // goverter:map Properties ServingEnvironmentId | MapPropertyServingEnvironmentId + // goverter:map . State | MapInferenceServiceState ConvertInferenceService(source *proto.Context) (*openapi.InferenceService, error) // goverter:map Name | MapNameFromOwned diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index cb22e248..b99f5fe8 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -84,6 +84,45 @@ func MapArtifactType(source *proto.Artifact) (string, error) { return "", fmt.Errorf("invalid artifact type found: %v", source.Type) } +func MapRegisteredModelState(source *proto.Context) *openapi.RegisteredModelState { + if source == nil || source.GetProperties() == nil { + return nil + } + + state, ok := source.GetProperties()["state"] + if !ok { + return nil + } + str := state.GetStringValue() + return (*openapi.RegisteredModelState)(&str) +} + +func MapModelVersionState(source *proto.Context) *openapi.ModelVersionState { + if source == nil || source.GetProperties() == nil { + return nil + } + + state, ok := source.GetProperties()["state"] + if !ok { + return nil + } + str := state.GetStringValue() + return (*openapi.ModelVersionState)(&str) +} + +func MapInferenceServiceState(source *proto.Context) *openapi.InferenceServiceState { + if source == nil || source.GetProperties() == nil { + return nil + } + + state, ok := source.GetProperties()["state"] + if !ok { + return nil + } + str := state.GetStringValue() + return (*openapi.InferenceServiceState)(&str) +} + func MapMLMDModelArtifactState(source *proto.Artifact_State) *openapi.ArtifactState { if source == nil { return nil diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index d3b28034..e65e604f 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -129,6 +129,14 @@ func MapRegisteredModelProperties(source *openapi.RegisteredModel) (map[string]* }, } } + + if source.State != nil { + props["state"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: string(*source.State), + }, + } + } } return props, nil } @@ -163,6 +171,15 @@ func MapModelVersionProperties(source *OpenAPIModelWrapper[openapi.ModelVersion] StringValue: *(*source.Model).Name, }, } + + if (*source.Model).State != nil { + props["state"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: string(*(*source.Model).State), + }, + } + } + // TODO: not available for now props["author"] = &proto.Value{ Value: &proto.Value_StringValue{ @@ -317,6 +334,14 @@ func MapInferenceServiceProperties(source *openapi.InferenceService) (map[string } } + if source.State != nil { + props["state"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: string(*source.State), + }, + } + } + registeredModelId, err := StringToInt64(&source.RegisteredModelId) if err != nil { return nil, err diff --git a/pkg/core/core.go b/pkg/core/core.go index 4c8116ef..188ea68d 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -43,6 +43,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, Name: registeredModelTypeName, Properties: map[string]proto.PropertyType{ "description": proto.PropertyType_STRING, + "state": proto.PropertyType_STRING, }, }, } @@ -56,6 +57,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, "model_name": proto.PropertyType_STRING, "version": proto.PropertyType_STRING, "author": proto.PropertyType_STRING, + "state": proto.PropertyType_STRING, }, }, } @@ -96,6 +98,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, // same information tracked using ParentContext association "serving_environment_id": proto.PropertyType_INT, "runtime": proto.PropertyType_STRING, + "state": proto.PropertyType_STRING, }, }, } diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index 0ad12243..a4cd99a5 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -311,14 +311,14 @@ func TestModelRegistryStartupWithExistingEmptyTypes(t *testing.T) { }) assertion.NotNilf(regModelResp.ContextType, "registered model type %s should exists", *registeredModelTypeName) assertion.Equal(*registeredModelTypeName, *regModelResp.ContextType.Name) - assertion.Equal(1, len(regModelResp.ContextType.Properties)) + assertion.Equal(2, len(regModelResp.ContextType.Properties)) modelVersionResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: modelVersionTypeName, }) assertion.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) assertion.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) - assertion.Equal(4, len(modelVersionResp.ContextType.Properties)) + assertion.Equal(5, len(modelVersionResp.ContextType.Properties)) modelArtifactResp, _ = client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, @@ -339,7 +339,7 @@ func TestModelRegistryStartupWithExistingEmptyTypes(t *testing.T) { }) assertion.NotNilf(inferenceServiceResp.ContextType, "inference service type %s should exists", *inferenceServiceTypeName) assertion.Equal(*inferenceServiceTypeName, *inferenceServiceResp.ContextType.Name) - assertion.Equal(5, len(inferenceServiceResp.ContextType.Properties)) + assertion.Equal(6, len(inferenceServiceResp.ContextType.Properties)) serveModelResp, _ = client.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ TypeName: serveModelTypeName, @@ -541,11 +541,13 @@ func TestCreateRegisteredModel(t *testing.T) { // create mode registry service service := initModelRegistryService(assertion, conn) + state := openapi.REGISTEREDMODELSTATE_ARCHIVED // register a new model registeredModel := &openapi.RegisteredModel{ Name: &modelName, ExternalID: &modelExternalId, Description: &modelDescription, + State: &state, CustomProperties: &map[string]openapi.MetadataValue{ "owner": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -574,6 +576,7 @@ func TestCreateRegisteredModel(t *testing.T) { assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") assertion.Equal(modelExternalId, *ctx.ExternalId, "saved external id should match the provided one") assertion.Equal(modelDescription, ctx.Properties["description"].GetStringValue(), "saved description should match the provided one") + assertion.Equal(string(state), ctx.Properties["state"].GetStringValue(), "saved state should match the provided one") assertion.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) @@ -678,10 +681,12 @@ func TestGetRegisteredModelById(t *testing.T) { // create mode registry service service := initModelRegistryService(assertion, conn) + state := openapi.REGISTEREDMODELSTATE_LIVE // register a new model registeredModel := &openapi.RegisteredModel{ Name: &modelName, ExternalID: &modelExternalId, + State: &state, CustomProperties: &map[string]openapi.MetadataValue{ "owner": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -703,6 +708,7 @@ func TestGetRegisteredModelById(t *testing.T) { // checks created model matches original one except for Id assertion.Equal(*registeredModel.Name, *getModelById.Name, "saved model name should match the original one") assertion.Equal(*registeredModel.ExternalID, *getModelById.ExternalID, "saved model external id should match the original one") + assertion.Equal(*registeredModel.State, *getModelById.State, "saved model state should match the original one") assertion.Equal(*registeredModel.CustomProperties, *getModelById.CustomProperties, "saved model custom props should match the original one") } @@ -965,10 +971,12 @@ func TestCreateModelVersion(t *testing.T) { registeredModelId := registerModel(assertion, service, nil, nil) + state := openapi.MODELVERSIONSTATE_LIVE modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, Description: &modelVersionDescription, + State: &state, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -998,6 +1006,7 @@ func TestCreateModelVersion(t *testing.T) { assertion.Equal(versionExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") assertion.Equal(modelVersionDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") + assertion.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) @@ -1175,9 +1184,11 @@ func TestGetModelVersionById(t *testing.T) { registeredModelId := registerModel(assertion, service, nil, nil) + state := openapi.MODELVERSIONSTATE_ARCHIVED modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, + State: &state, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -1204,10 +1215,11 @@ func TestGetModelVersionById(t *testing.T) { assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*getById.Id, *converter.Int64ToString(ctx.Id), "returned model version id should match the mlmd context one") - assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getById.Name), *ctx.Name, "saved model name should match the provided one") - assertion.Equal(*getById.ExternalID, *modelVersion.ExternalID, "saved external id should match the provided one") - assertion.Equal(*(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, author, "saved author custom property should match the provided one") + assertion.Equal(*converter.Int64ToString(ctx.Id), *getById.Id, "returned model version id should match the mlmd context one") + assertion.Equal(*modelVersion.Name, *getById.Name, "saved model name should match the provided one") + assertion.Equal(*modelVersion.ExternalID, *getById.ExternalID, "saved external id should match the provided one") + assertion.Equal(*modelVersion.State, *getById.State, "saved model state should match the original one") + assertion.Equal(author, *(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") } func TestGetModelVersionByParamsWithNoResults(t *testing.T) { @@ -2289,6 +2301,7 @@ func TestCreateInferenceService(t *testing.T) { parentResourceId := registerServingEnvironment(assertion, service, nil, nil) registeredModelId := registerModel(assertion, service, nil, nil) runtime := "model-server" + state := openapi.INFERENCESERVICESTATE_DEPLOYED eut := &openapi.InferenceService{ Name: &entityName, @@ -2297,6 +2310,7 @@ func TestCreateInferenceService(t *testing.T) { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, Runtime: &runtime, + State: &state, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -2327,6 +2341,7 @@ func TestCreateInferenceService(t *testing.T) { assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") assertion.Equal(entityDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") assertion.Equal(runtime, byId.Contexts[0].Properties["runtime"].GetStringValue(), "saved runtime should match the provided one") + assertion.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) @@ -2518,12 +2533,14 @@ func TestGetInferenceServiceById(t *testing.T) { parentResourceId := registerServingEnvironment(assertion, service, nil, nil) registeredModelId := registerModel(assertion, service, nil, nil) + state := openapi.INFERENCESERVICESTATE_UNDEPLOYED eut := &openapi.InferenceService{ Name: &entityName, ExternalID: &entityExternalId2, Description: &entityDescription, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, + State: &state, CustomProperties: &map[string]openapi.MetadataValue{ "author": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -2551,8 +2568,9 @@ func TestGetInferenceServiceById(t *testing.T) { ctx := ctxById.Contexts[0] assertion.Equal(*getById.Id, *converter.Int64ToString(ctx.Id), "returned id should match the mlmd context one") - assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getById.Name), *ctx.Name, "saved name should match the provided one") - assertion.Equal(*getById.ExternalID, *eut.ExternalID, "saved external id should match the provided one") + assertion.Equal(*eut.Name, *getById.Name, "saved name should match the provided one") + assertion.Equal(*eut.ExternalID, *getById.ExternalID, "saved external id should match the provided one") + assertion.Equal(*eut.State, *getById.State, "saved state should match the provided one") assertion.Equal(*(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, author, "saved author custom property should match the provided one") } diff --git a/pkg/openapi/.openapi-generator/FILES b/pkg/openapi/.openapi-generator/FILES index 9b78767d..6f119555 100644 --- a/pkg/openapi/.openapi-generator/FILES +++ b/pkg/openapi/.openapi-generator/FILES @@ -19,6 +19,7 @@ model_execution_state.go model_inference_service.go model_inference_service_create.go model_inference_service_list.go +model_inference_service_state.go model_inference_service_update.go model_metadata_bool_value.go model_metadata_double_value.go @@ -34,11 +35,13 @@ model_model_artifact_update.go model_model_version.go model_model_version_create.go model_model_version_list.go +model_model_version_state.go model_model_version_update.go model_order_by_field.go model_registered_model.go model_registered_model_create.go model_registered_model_list.go +model_registered_model_state.go model_registered_model_update.go model_serve_model.go model_serve_model_create.go diff --git a/pkg/openapi/model_inference_service.go b/pkg/openapi/model_inference_service.go index 9aa49ab1..c20699c3 100644 --- a/pkg/openapi/model_inference_service.go +++ b/pkg/openapi/model_inference_service.go @@ -36,7 +36,8 @@ type InferenceService struct { // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` // Model runtime. - Runtime *string `json:"runtime,omitempty"` + Runtime *string `json:"runtime,omitempty"` + State *InferenceServiceState `json:"state,omitempty"` // ID of the `RegisteredModel` to serve. RegisteredModelId string `json:"registeredModelId"` // ID of the parent `ServingEnvironment` for this `InferenceService` entity. @@ -49,6 +50,8 @@ type InferenceService struct { // will change when the set of required properties is changed func NewInferenceService(registeredModelId string, servingEnvironmentId string) *InferenceService { this := InferenceService{} + var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.State = &state this.RegisteredModelId = registeredModelId this.ServingEnvironmentId = servingEnvironmentId return &this @@ -59,6 +62,8 @@ func NewInferenceService(registeredModelId string, servingEnvironmentId string) // but it doesn't guarantee that properties required by API are set func NewInferenceServiceWithDefaults() *InferenceService { this := InferenceService{} + var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.State = &state return &this } @@ -350,6 +355,38 @@ func (o *InferenceService) SetRuntime(v string) { o.Runtime = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *InferenceService) GetState() InferenceServiceState { + if o == nil || IsNil(o.State) { + var ret InferenceServiceState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceService) GetStateOk() (*InferenceServiceState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *InferenceService) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given InferenceServiceState and assigns it to the State field. +func (o *InferenceService) SetState(v InferenceServiceState) { + o.State = &v +} + // GetRegisteredModelId returns the RegisteredModelId field value func (o *InferenceService) GetRegisteredModelId() string { if o == nil { @@ -435,6 +472,9 @@ func (o InferenceService) ToMap() (map[string]interface{}, error) { if !IsNil(o.Runtime) { toSerialize["runtime"] = o.Runtime } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } toSerialize["registeredModelId"] = o.RegisteredModelId toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId return toSerialize, nil diff --git a/pkg/openapi/model_inference_service_create.go b/pkg/openapi/model_inference_service_create.go index 178f1189..b4299de6 100644 --- a/pkg/openapi/model_inference_service_create.go +++ b/pkg/openapi/model_inference_service_create.go @@ -30,7 +30,8 @@ type InferenceServiceCreate struct { // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` // Model runtime. - Runtime *string `json:"runtime,omitempty"` + Runtime *string `json:"runtime,omitempty"` + State *InferenceServiceState `json:"state,omitempty"` // ID of the `RegisteredModel` to serve. RegisteredModelId string `json:"registeredModelId"` // ID of the parent `ServingEnvironment` for this `InferenceService` entity. @@ -43,6 +44,8 @@ type InferenceServiceCreate struct { // will change when the set of required properties is changed func NewInferenceServiceCreate(registeredModelId string, servingEnvironmentId string) *InferenceServiceCreate { this := InferenceServiceCreate{} + var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.State = &state this.RegisteredModelId = registeredModelId this.ServingEnvironmentId = servingEnvironmentId return &this @@ -53,6 +56,8 @@ func NewInferenceServiceCreate(registeredModelId string, servingEnvironmentId st // but it doesn't guarantee that properties required by API are set func NewInferenceServiceCreateWithDefaults() *InferenceServiceCreate { this := InferenceServiceCreate{} + var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.State = &state return &this } @@ -248,6 +253,38 @@ func (o *InferenceServiceCreate) SetRuntime(v string) { o.Runtime = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetState() InferenceServiceState { + if o == nil || IsNil(o.State) { + var ret InferenceServiceState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceCreate) GetStateOk() (*InferenceServiceState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given InferenceServiceState and assigns it to the State field. +func (o *InferenceServiceCreate) SetState(v InferenceServiceState) { + o.State = &v +} + // GetRegisteredModelId returns the RegisteredModelId field value func (o *InferenceServiceCreate) GetRegisteredModelId() string { if o == nil { @@ -324,6 +361,9 @@ func (o InferenceServiceCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.Runtime) { toSerialize["runtime"] = o.Runtime } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } toSerialize["registeredModelId"] = o.RegisteredModelId toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId return toSerialize, nil diff --git a/pkg/openapi/model_inference_service_state.go b/pkg/openapi/model_inference_service_state.go new file mode 100644 index 00000000..84c39e0b --- /dev/null +++ b/pkg/openapi/model_inference_service_state.go @@ -0,0 +1,110 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// InferenceServiceState - DEPLOYED: A state indicating that the `InferenceService` should be deployed. - UNDEPLOYED: A state indicating that the `InferenceService` should be un-deployed. The state indicates the desired state of inference service. See the associated `ServeModel` for the actual status of service deployment action. +type InferenceServiceState string + +// List of InferenceServiceState +const ( + INFERENCESERVICESTATE_DEPLOYED InferenceServiceState = "DEPLOYED" + INFERENCESERVICESTATE_UNDEPLOYED InferenceServiceState = "UNDEPLOYED" +) + +// All allowed values of InferenceServiceState enum +var AllowedInferenceServiceStateEnumValues = []InferenceServiceState{ + "DEPLOYED", + "UNDEPLOYED", +} + +func (v *InferenceServiceState) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := InferenceServiceState(value) + for _, existing := range AllowedInferenceServiceStateEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid InferenceServiceState", value) +} + +// NewInferenceServiceStateFromValue returns a pointer to a valid InferenceServiceState +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewInferenceServiceStateFromValue(v string) (*InferenceServiceState, error) { + ev := InferenceServiceState(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for InferenceServiceState: valid values are %v", v, AllowedInferenceServiceStateEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v InferenceServiceState) IsValid() bool { + for _, existing := range AllowedInferenceServiceStateEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to InferenceServiceState value +func (v InferenceServiceState) Ptr() *InferenceServiceState { + return &v +} + +type NullableInferenceServiceState struct { + value *InferenceServiceState + isSet bool +} + +func (v NullableInferenceServiceState) Get() *InferenceServiceState { + return v.value +} + +func (v *NullableInferenceServiceState) Set(val *InferenceServiceState) { + v.value = val + v.isSet = true +} + +func (v NullableInferenceServiceState) IsSet() bool { + return v.isSet +} + +func (v *NullableInferenceServiceState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInferenceServiceState(val *InferenceServiceState) *NullableInferenceServiceState { + return &NullableInferenceServiceState{value: val, isSet: true} +} + +func (v NullableInferenceServiceState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInferenceServiceState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/openapi/model_inference_service_update.go b/pkg/openapi/model_inference_service_update.go index 0094cc74..af13e648 100644 --- a/pkg/openapi/model_inference_service_update.go +++ b/pkg/openapi/model_inference_service_update.go @@ -28,7 +28,8 @@ type InferenceServiceUpdate struct { // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` // Model runtime. - Runtime *string `json:"runtime,omitempty"` + Runtime *string `json:"runtime,omitempty"` + State *InferenceServiceState `json:"state,omitempty"` } // NewInferenceServiceUpdate instantiates a new InferenceServiceUpdate object @@ -37,6 +38,8 @@ type InferenceServiceUpdate struct { // will change when the set of required properties is changed func NewInferenceServiceUpdate() *InferenceServiceUpdate { this := InferenceServiceUpdate{} + var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.State = &state return &this } @@ -45,6 +48,8 @@ func NewInferenceServiceUpdate() *InferenceServiceUpdate { // but it doesn't guarantee that properties required by API are set func NewInferenceServiceUpdateWithDefaults() *InferenceServiceUpdate { this := InferenceServiceUpdate{} + var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.State = &state return &this } @@ -208,6 +213,38 @@ func (o *InferenceServiceUpdate) SetRuntime(v string) { o.Runtime = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *InferenceServiceUpdate) GetState() InferenceServiceState { + if o == nil || IsNil(o.State) { + var ret InferenceServiceState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *InferenceServiceUpdate) GetStateOk() (*InferenceServiceState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *InferenceServiceUpdate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given InferenceServiceState and assigns it to the State field. +func (o *InferenceServiceUpdate) SetState(v InferenceServiceState) { + o.State = &v +} + func (o InferenceServiceUpdate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -233,6 +270,9 @@ func (o InferenceServiceUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.Runtime) { toSerialize["runtime"] = o.Runtime } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } return toSerialize, nil } diff --git a/pkg/openapi/model_model_version.go b/pkg/openapi/model_model_version.go index 335bcb16..1687774f 100644 --- a/pkg/openapi/model_model_version.go +++ b/pkg/openapi/model_model_version.go @@ -26,7 +26,8 @@ type ModelVersion struct { // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. - Name *string `json:"name,omitempty"` + Name *string `json:"name,omitempty"` + State *ModelVersionState `json:"state,omitempty"` // Output only. The unique server generated id of the resource. Id *string `json:"id,omitempty"` // Output only. Create time of the resource in millisecond since epoch. @@ -41,6 +42,8 @@ type ModelVersion struct { // will change when the set of required properties is changed func NewModelVersion() *ModelVersion { this := ModelVersion{} + var state ModelVersionState = MODELVERSIONSTATE_LIVE + this.State = &state return &this } @@ -49,6 +52,8 @@ func NewModelVersion() *ModelVersion { // but it doesn't guarantee that properties required by API are set func NewModelVersionWithDefaults() *ModelVersion { this := ModelVersion{} + var state ModelVersionState = MODELVERSIONSTATE_LIVE + this.State = &state return &this } @@ -180,6 +185,38 @@ func (o *ModelVersion) SetName(v string) { o.Name = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *ModelVersion) GetState() ModelVersionState { + if o == nil || IsNil(o.State) { + var ret ModelVersionState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetStateOk() (*ModelVersionState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *ModelVersion) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ModelVersionState and assigns it to the State field. +func (o *ModelVersion) SetState(v ModelVersionState) { + o.State = &v +} + // GetId returns the Id field value if set, zero value otherwise. func (o *ModelVersion) GetId() string { if o == nil || IsNil(o.Id) { @@ -298,6 +335,9 @@ func (o ModelVersion) ToMap() (map[string]interface{}, error) { if !IsNil(o.Name) { toSerialize["name"] = o.Name } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } if !IsNil(o.Id) { toSerialize["id"] = o.Id } diff --git a/pkg/openapi/model_model_version_create.go b/pkg/openapi/model_model_version_create.go index ae0255d7..9908ad52 100644 --- a/pkg/openapi/model_model_version_create.go +++ b/pkg/openapi/model_model_version_create.go @@ -28,7 +28,8 @@ type ModelVersionCreate struct { // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. - Name *string `json:"name,omitempty"` + Name *string `json:"name,omitempty"` + State *ModelVersionState `json:"state,omitempty"` } // NewModelVersionCreate instantiates a new ModelVersionCreate object @@ -37,6 +38,8 @@ type ModelVersionCreate struct { // will change when the set of required properties is changed func NewModelVersionCreate(registeredModelID string) *ModelVersionCreate { this := ModelVersionCreate{} + var state ModelVersionState = MODELVERSIONSTATE_LIVE + this.State = &state return &this } @@ -45,6 +48,8 @@ func NewModelVersionCreate(registeredModelID string) *ModelVersionCreate { // but it doesn't guarantee that properties required by API are set func NewModelVersionCreateWithDefaults() *ModelVersionCreate { this := ModelVersionCreate{} + var state ModelVersionState = MODELVERSIONSTATE_LIVE + this.State = &state return &this } @@ -200,6 +205,38 @@ func (o *ModelVersionCreate) SetName(v string) { o.Name = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *ModelVersionCreate) GetState() ModelVersionState { + if o == nil || IsNil(o.State) { + var ret ModelVersionState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionCreate) GetStateOk() (*ModelVersionState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *ModelVersionCreate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ModelVersionState and assigns it to the State field. +func (o *ModelVersionCreate) SetState(v ModelVersionState) { + o.State = &v +} + func (o ModelVersionCreate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -223,6 +260,9 @@ func (o ModelVersionCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.Name) { toSerialize["name"] = o.Name } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } return toSerialize, nil } diff --git a/pkg/openapi/model_model_version_state.go b/pkg/openapi/model_model_version_state.go new file mode 100644 index 00000000..802c7e60 --- /dev/null +++ b/pkg/openapi/model_model_version_state.go @@ -0,0 +1,110 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// ModelVersionState - LIVE: A state indicating that the `ModelVersion` exists - ARCHIVED: A state indicating that the `ModelVersion` has been archived. +type ModelVersionState string + +// List of ModelVersionState +const ( + MODELVERSIONSTATE_LIVE ModelVersionState = "LIVE" + MODELVERSIONSTATE_ARCHIVED ModelVersionState = "ARCHIVED" +) + +// All allowed values of ModelVersionState enum +var AllowedModelVersionStateEnumValues = []ModelVersionState{ + "LIVE", + "ARCHIVED", +} + +func (v *ModelVersionState) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := ModelVersionState(value) + for _, existing := range AllowedModelVersionStateEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid ModelVersionState", value) +} + +// NewModelVersionStateFromValue returns a pointer to a valid ModelVersionState +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewModelVersionStateFromValue(v string) (*ModelVersionState, error) { + ev := ModelVersionState(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for ModelVersionState: valid values are %v", v, AllowedModelVersionStateEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v ModelVersionState) IsValid() bool { + for _, existing := range AllowedModelVersionStateEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to ModelVersionState value +func (v ModelVersionState) Ptr() *ModelVersionState { + return &v +} + +type NullableModelVersionState struct { + value *ModelVersionState + isSet bool +} + +func (v NullableModelVersionState) Get() *ModelVersionState { + return v.value +} + +func (v *NullableModelVersionState) Set(val *ModelVersionState) { + v.value = val + v.isSet = true +} + +func (v NullableModelVersionState) IsSet() bool { + return v.isSet +} + +func (v *NullableModelVersionState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableModelVersionState(val *ModelVersionState) *NullableModelVersionState { + return &NullableModelVersionState{value: val, isSet: true} +} + +func (v NullableModelVersionState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableModelVersionState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/openapi/model_model_version_update.go b/pkg/openapi/model_model_version_update.go index 0c35eb2a..3bc7ca7d 100644 --- a/pkg/openapi/model_model_version_update.go +++ b/pkg/openapi/model_model_version_update.go @@ -24,7 +24,8 @@ type ModelVersionUpdate struct { // An optional description about the resource. Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. - ExternalID *string `json:"externalID,omitempty"` + ExternalID *string `json:"externalID,omitempty"` + State *ModelVersionState `json:"state,omitempty"` } // NewModelVersionUpdate instantiates a new ModelVersionUpdate object @@ -33,6 +34,8 @@ type ModelVersionUpdate struct { // will change when the set of required properties is changed func NewModelVersionUpdate() *ModelVersionUpdate { this := ModelVersionUpdate{} + var state ModelVersionState = MODELVERSIONSTATE_LIVE + this.State = &state return &this } @@ -41,6 +44,8 @@ func NewModelVersionUpdate() *ModelVersionUpdate { // but it doesn't guarantee that properties required by API are set func NewModelVersionUpdateWithDefaults() *ModelVersionUpdate { this := ModelVersionUpdate{} + var state ModelVersionState = MODELVERSIONSTATE_LIVE + this.State = &state return &this } @@ -140,6 +145,38 @@ func (o *ModelVersionUpdate) SetExternalID(v string) { o.ExternalID = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *ModelVersionUpdate) GetState() ModelVersionState { + if o == nil || IsNil(o.State) { + var ret ModelVersionState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionUpdate) GetStateOk() (*ModelVersionState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *ModelVersionUpdate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ModelVersionState and assigns it to the State field. +func (o *ModelVersionUpdate) SetState(v ModelVersionState) { + o.State = &v +} + func (o ModelVersionUpdate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -159,6 +196,9 @@ func (o ModelVersionUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } return toSerialize, nil } diff --git a/pkg/openapi/model_registered_model.go b/pkg/openapi/model_registered_model.go index e1efa2dd..9ed0d47d 100644 --- a/pkg/openapi/model_registered_model.go +++ b/pkg/openapi/model_registered_model.go @@ -32,7 +32,8 @@ type RegisteredModel struct { // Output only. Create time of the resource in millisecond since epoch. CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` // Output only. Last update time of the resource since epoch in millisecond since epoch. - LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` + State *RegisteredModelState `json:"state,omitempty"` } // NewRegisteredModel instantiates a new RegisteredModel object @@ -41,6 +42,8 @@ type RegisteredModel struct { // will change when the set of required properties is changed func NewRegisteredModel() *RegisteredModel { this := RegisteredModel{} + var state RegisteredModelState = REGISTEREDMODELSTATE_LIVE + this.State = &state return &this } @@ -49,6 +52,8 @@ func NewRegisteredModel() *RegisteredModel { // but it doesn't guarantee that properties required by API are set func NewRegisteredModelWithDefaults() *RegisteredModel { this := RegisteredModel{} + var state RegisteredModelState = REGISTEREDMODELSTATE_LIVE + this.State = &state return &this } @@ -276,6 +281,38 @@ func (o *RegisteredModel) SetLastUpdateTimeSinceEpoch(v string) { o.LastUpdateTimeSinceEpoch = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *RegisteredModel) GetState() RegisteredModelState { + if o == nil || IsNil(o.State) { + var ret RegisteredModelState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModel) GetStateOk() (*RegisteredModelState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *RegisteredModel) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given RegisteredModelState and assigns it to the State field. +func (o *RegisteredModel) SetState(v RegisteredModelState) { + o.State = &v +} + func (o RegisteredModel) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -307,6 +344,9 @@ func (o RegisteredModel) ToMap() (map[string]interface{}, error) { if !IsNil(o.LastUpdateTimeSinceEpoch) { toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } return toSerialize, nil } diff --git a/pkg/openapi/model_registered_model_create.go b/pkg/openapi/model_registered_model_create.go index 26708045..b03d8f64 100644 --- a/pkg/openapi/model_registered_model_create.go +++ b/pkg/openapi/model_registered_model_create.go @@ -26,7 +26,8 @@ type RegisteredModelCreate struct { // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. - Name *string `json:"name,omitempty"` + Name *string `json:"name,omitempty"` + State *RegisteredModelState `json:"state,omitempty"` } // NewRegisteredModelCreate instantiates a new RegisteredModelCreate object @@ -35,6 +36,8 @@ type RegisteredModelCreate struct { // will change when the set of required properties is changed func NewRegisteredModelCreate() *RegisteredModelCreate { this := RegisteredModelCreate{} + var state RegisteredModelState = REGISTEREDMODELSTATE_LIVE + this.State = &state return &this } @@ -43,6 +46,8 @@ func NewRegisteredModelCreate() *RegisteredModelCreate { // but it doesn't guarantee that properties required by API are set func NewRegisteredModelCreateWithDefaults() *RegisteredModelCreate { this := RegisteredModelCreate{} + var state RegisteredModelState = REGISTEREDMODELSTATE_LIVE + this.State = &state return &this } @@ -174,6 +179,38 @@ func (o *RegisteredModelCreate) SetName(v string) { o.Name = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *RegisteredModelCreate) GetState() RegisteredModelState { + if o == nil || IsNil(o.State) { + var ret RegisteredModelState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelCreate) GetStateOk() (*RegisteredModelState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *RegisteredModelCreate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given RegisteredModelState and assigns it to the State field. +func (o *RegisteredModelCreate) SetState(v RegisteredModelState) { + o.State = &v +} + func (o RegisteredModelCreate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -196,6 +233,9 @@ func (o RegisteredModelCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.Name) { toSerialize["name"] = o.Name } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } return toSerialize, nil } diff --git a/pkg/openapi/model_registered_model_state.go b/pkg/openapi/model_registered_model_state.go new file mode 100644 index 00000000..6ceb12dc --- /dev/null +++ b/pkg/openapi/model_registered_model_state.go @@ -0,0 +1,110 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: 1.0.0 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" + "fmt" +) + +// RegisteredModelState - LIVE: A state indicating that the `RegisteredModel` exists - ARCHIVED: A state indicating that the `RegisteredModel` has been archived. +type RegisteredModelState string + +// List of RegisteredModelState +const ( + REGISTEREDMODELSTATE_LIVE RegisteredModelState = "LIVE" + REGISTEREDMODELSTATE_ARCHIVED RegisteredModelState = "ARCHIVED" +) + +// All allowed values of RegisteredModelState enum +var AllowedRegisteredModelStateEnumValues = []RegisteredModelState{ + "LIVE", + "ARCHIVED", +} + +func (v *RegisteredModelState) UnmarshalJSON(src []byte) error { + var value string + err := json.Unmarshal(src, &value) + if err != nil { + return err + } + enumTypeValue := RegisteredModelState(value) + for _, existing := range AllowedRegisteredModelStateEnumValues { + if existing == enumTypeValue { + *v = enumTypeValue + return nil + } + } + + return fmt.Errorf("%+v is not a valid RegisteredModelState", value) +} + +// NewRegisteredModelStateFromValue returns a pointer to a valid RegisteredModelState +// for the value passed as argument, or an error if the value passed is not allowed by the enum +func NewRegisteredModelStateFromValue(v string) (*RegisteredModelState, error) { + ev := RegisteredModelState(v) + if ev.IsValid() { + return &ev, nil + } else { + return nil, fmt.Errorf("invalid value '%v' for RegisteredModelState: valid values are %v", v, AllowedRegisteredModelStateEnumValues) + } +} + +// IsValid return true if the value is valid for the enum, false otherwise +func (v RegisteredModelState) IsValid() bool { + for _, existing := range AllowedRegisteredModelStateEnumValues { + if existing == v { + return true + } + } + return false +} + +// Ptr returns reference to RegisteredModelState value +func (v RegisteredModelState) Ptr() *RegisteredModelState { + return &v +} + +type NullableRegisteredModelState struct { + value *RegisteredModelState + isSet bool +} + +func (v NullableRegisteredModelState) Get() *RegisteredModelState { + return v.value +} + +func (v *NullableRegisteredModelState) Set(val *RegisteredModelState) { + v.value = val + v.isSet = true +} + +func (v NullableRegisteredModelState) IsSet() bool { + return v.isSet +} + +func (v *NullableRegisteredModelState) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableRegisteredModelState(val *RegisteredModelState) *NullableRegisteredModelState { + return &NullableRegisteredModelState{value: val, isSet: true} +} + +func (v NullableRegisteredModelState) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableRegisteredModelState) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/pkg/openapi/model_registered_model_update.go b/pkg/openapi/model_registered_model_update.go index bed6283c..fc8f64d3 100644 --- a/pkg/openapi/model_registered_model_update.go +++ b/pkg/openapi/model_registered_model_update.go @@ -24,7 +24,8 @@ type RegisteredModelUpdate struct { // An optional description about the resource. Description *string `json:"description,omitempty"` // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. - ExternalID *string `json:"externalID,omitempty"` + ExternalID *string `json:"externalID,omitempty"` + State *RegisteredModelState `json:"state,omitempty"` } // NewRegisteredModelUpdate instantiates a new RegisteredModelUpdate object @@ -33,6 +34,8 @@ type RegisteredModelUpdate struct { // will change when the set of required properties is changed func NewRegisteredModelUpdate() *RegisteredModelUpdate { this := RegisteredModelUpdate{} + var state RegisteredModelState = REGISTEREDMODELSTATE_LIVE + this.State = &state return &this } @@ -41,6 +44,8 @@ func NewRegisteredModelUpdate() *RegisteredModelUpdate { // but it doesn't guarantee that properties required by API are set func NewRegisteredModelUpdateWithDefaults() *RegisteredModelUpdate { this := RegisteredModelUpdate{} + var state RegisteredModelState = REGISTEREDMODELSTATE_LIVE + this.State = &state return &this } @@ -140,6 +145,38 @@ func (o *RegisteredModelUpdate) SetExternalID(v string) { o.ExternalID = &v } +// GetState returns the State field value if set, zero value otherwise. +func (o *RegisteredModelUpdate) GetState() RegisteredModelState { + if o == nil || IsNil(o.State) { + var ret RegisteredModelState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *RegisteredModelUpdate) GetStateOk() (*RegisteredModelState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *RegisteredModelUpdate) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given RegisteredModelState and assigns it to the State field. +func (o *RegisteredModelUpdate) SetState(v RegisteredModelState) { + o.State = &v +} + func (o RegisteredModelUpdate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -159,6 +196,9 @@ func (o RegisteredModelUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } return toSerialize, nil } From 06ea855cbeabca7ec73f634a404f6afdb45a552d Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 23 Nov 2023 15:15:16 +0100 Subject: [PATCH 153/254] Add autogenerated type asserts for new states (#197) --- internal/server/openapi/type_asserts.go | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go index 07a7e94b..38ed51dd 100644 --- a/internal/server/openapi/type_asserts.go +++ b/internal/server/openapi/type_asserts.go @@ -287,6 +287,16 @@ func AssertInferenceServiceListConstraints(obj model.InferenceServiceList) error return nil } +// AssertInferenceServiceStateRequired checks if the required fields are not zero-ed +func AssertInferenceServiceStateRequired(obj model.InferenceServiceState) error { + return nil +} + +// AssertInferenceServiceStateConstraints checks if the values respects the defined constraints +func AssertInferenceServiceStateConstraints(obj model.InferenceServiceState) error { + return nil +} + // AssertInferenceServiceUpdateRequired checks if the required fields are not zero-ed func AssertInferenceServiceUpdateRequired(obj model.InferenceServiceUpdate) error { return nil @@ -487,6 +497,16 @@ func AssertModelVersionListConstraints(obj model.ModelVersionList) error { return nil } +// AssertModelVersionStateRequired checks if the required fields are not zero-ed +func AssertModelVersionStateRequired(obj model.ModelVersionState) error { + return nil +} + +// AssertModelVersionStateConstraints checks if the values respects the defined constraints +func AssertModelVersionStateConstraints(obj model.ModelVersionState) error { + return nil +} + // AssertModelVersionUpdateRequired checks if the required fields are not zero-ed func AssertModelVersionUpdateRequired(obj model.ModelVersionUpdate) error { return nil @@ -553,6 +573,16 @@ func AssertRegisteredModelListConstraints(obj model.RegisteredModelList) error { return nil } +// AssertRegisteredModelStateRequired checks if the required fields are not zero-ed +func AssertRegisteredModelStateRequired(obj model.RegisteredModelState) error { + return nil +} + +// AssertRegisteredModelStateConstraints checks if the values respects the defined constraints +func AssertRegisteredModelStateConstraints(obj model.RegisteredModelState) error { + return nil +} + // AssertRegisteredModelUpdateRequired checks if the required fields are not zero-ed func AssertRegisteredModelUpdateRequired(obj model.RegisteredModelUpdate) error { return nil From 2fac15092d90f13710c3d4a6fdb7754227d9ab2c Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Mon, 27 Nov 2023 09:35:11 +0100 Subject: [PATCH 154/254] Override not editable fields during updates (#200) * Override not editable fields during updates * Setup test for not editable fields override --- .gitignore | 1 + Makefile | 2 +- .../generated/openapi_converter.gen.go | 125 +++++++++++++- internal/converter/opeanpi_converter.go | 41 +++++ internal/converter/openapi_converter_test.go | 160 ++++++++++++++++++ internal/converter/openapi_converter_util.go | 71 ++++++++ pkg/core/core.go | 73 ++++---- pkg/core/core_test.go | 16 +- 8 files changed, 457 insertions(+), 32 deletions(-) create mode 100644 internal/converter/openapi_converter_test.go create mode 100644 internal/converter/openapi_converter_util.go diff --git a/.gitignore b/.gitignore index 391945a9..08c515b9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ model-registry metadata.sqlite.db vendor +coverage.txt # Robot Framework files log.html diff --git a/Makefile b/Makefile index c38838e3..9024695e 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,7 @@ bin/golangci-lint: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.54.2 bin/goverter: - GOBIN=$(PROJECT_PATH)/bin go install github.com/jmattheis/goverter/cmd/goverter@v1.0.0 + GOBIN=$(PROJECT_PATH)/bin go install github.com/jmattheis/goverter/cmd/goverter@v1.1.1 OPENAPI_GENERATOR ?= ${PROJECT_BIN}/openapi-generator-cli NPM ?= "$(shell which npm)" diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index 8f98e9b4..f1334c9f 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -2,7 +2,10 @@ package generated -import openapi "github.com/opendatahub-io/model-registry/pkg/openapi" +import ( + converter "github.com/opendatahub-io/model-registry/internal/converter" + openapi "github.com/opendatahub-io/model-registry/pkg/openapi" +) type OpenAPIConverterImpl struct{} @@ -549,6 +552,126 @@ func (c *OpenAPIConverterImpl) ConvertServingEnvironmentUpdate(source *openapi.S } return pOpenapiServingEnvironment, nil } +func (c *OpenAPIConverterImpl) OverrideNotEditableForInferenceService(source converter.OpenapiUpdateWrapper[openapi.InferenceService]) (openapi.InferenceService, error) { + openapiInferenceService := converter.InitInferenceServiceWithUpdate(source) + var pString *string + if source.Existing != nil { + pString = source.Existing.Name + } + var pString2 *string + if pString != nil { + xstring := *pString + pString2 = &xstring + } + openapiInferenceService.Name = pString2 + var pString3 *string + if source.Existing != nil { + pString3 = &source.Existing.RegisteredModelId + } + var xstring2 string + if pString3 != nil { + xstring2 = *pString3 + } + openapiInferenceService.RegisteredModelId = xstring2 + var pString4 *string + if source.Existing != nil { + pString4 = &source.Existing.ServingEnvironmentId + } + var xstring3 string + if pString4 != nil { + xstring3 = *pString4 + } + openapiInferenceService.ServingEnvironmentId = xstring3 + return openapiInferenceService, nil +} +func (c *OpenAPIConverterImpl) OverrideNotEditableForModelArtifact(source converter.OpenapiUpdateWrapper[openapi.ModelArtifact]) (openapi.ModelArtifact, error) { + openapiModelArtifact := converter.InitModelArtifactWithUpdate(source) + var pString *string + if source.Existing != nil { + pString = source.Existing.Name + } + var pString2 *string + if pString != nil { + xstring := *pString + pString2 = &xstring + } + openapiModelArtifact.Name = pString2 + var pString3 *string + if source.Existing != nil { + pString3 = &source.Existing.ArtifactType + } + var xstring2 string + if pString3 != nil { + xstring2 = *pString3 + } + openapiModelArtifact.ArtifactType = xstring2 + return openapiModelArtifact, nil +} +func (c *OpenAPIConverterImpl) OverrideNotEditableForModelVersion(source converter.OpenapiUpdateWrapper[openapi.ModelVersion]) (openapi.ModelVersion, error) { + openapiModelVersion := converter.InitModelVersionWithUpdate(source) + var pString *string + if source.Existing != nil { + pString = source.Existing.Name + } + var pString2 *string + if pString != nil { + xstring := *pString + pString2 = &xstring + } + openapiModelVersion.Name = pString2 + return openapiModelVersion, nil +} +func (c *OpenAPIConverterImpl) OverrideNotEditableForRegisteredModel(source converter.OpenapiUpdateWrapper[openapi.RegisteredModel]) (openapi.RegisteredModel, error) { + openapiRegisteredModel := converter.InitRegisteredModelWithUpdate(source) + var pString *string + if source.Existing != nil { + pString = source.Existing.Name + } + var pString2 *string + if pString != nil { + xstring := *pString + pString2 = &xstring + } + openapiRegisteredModel.Name = pString2 + return openapiRegisteredModel, nil +} +func (c *OpenAPIConverterImpl) OverrideNotEditableForServeModel(source converter.OpenapiUpdateWrapper[openapi.ServeModel]) (openapi.ServeModel, error) { + openapiServeModel := converter.InitServeModelWithUpdate(source) + var pString *string + if source.Existing != nil { + pString = source.Existing.Name + } + var pString2 *string + if pString != nil { + xstring := *pString + pString2 = &xstring + } + openapiServeModel.Name = pString2 + var pString3 *string + if source.Existing != nil { + pString3 = &source.Existing.ModelVersionId + } + var xstring2 string + if pString3 != nil { + xstring2 = *pString3 + } + openapiServeModel.ModelVersionId = xstring2 + return openapiServeModel, nil +} +func (c *OpenAPIConverterImpl) OverrideNotEditableForServingEnvironment(source converter.OpenapiUpdateWrapper[openapi.ServingEnvironment]) (openapi.ServingEnvironment, error) { + openapiServingEnvironment := converter.InitServingEnvironmentWithUpdate(source) + var pString *string + if source.Existing != nil { + pString = source.Existing.Name + } + var pString2 *string + if pString != nil { + xstring := *pString + pString2 = &xstring + } + openapiServingEnvironment.Name = pString2 + return openapiServingEnvironment, nil +} func (c *OpenAPIConverterImpl) openapiMetadataValueToOpenapiMetadataValue(source openapi.MetadataValue) openapi.MetadataValue { var openapiMetadataValue openapi.MetadataValue openapiMetadataValue.MetadataBoolValue = c.pOpenapiMetadataBoolValueToPOpenapiMetadataBoolValue(source.MetadataBoolValue) diff --git a/internal/converter/opeanpi_converter.go b/internal/converter/opeanpi_converter.go index 46163b85..230fc2e4 100644 --- a/internal/converter/opeanpi_converter.go +++ b/internal/converter/opeanpi_converter.go @@ -2,6 +2,11 @@ package converter import "github.com/opendatahub-io/model-registry/pkg/openapi" +// NOTE: methods must follow these patterns, otherwise tests could not find possible issues: +// Converters createEntity to entity: ConvertCreate +// Converters updateEntity to entity: ConvertUpdate +// Converters override fields entity: OverrideNotEditableFor + // goverter:converter // goverter:output:file ./generated/openapi_converter.gen.go // goverter:wrapErrors @@ -43,4 +48,40 @@ type OpenAPIConverter interface { // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Name ModelVersionId ConvertServeModelUpdate(source *openapi.ServeModelUpdate) (*openapi.ServeModel, error) + + // Ignore all fields that ARE editable + // goverter:default InitRegisteredModelWithUpdate + // goverter:autoMap Existing + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties State + OverrideNotEditableForRegisteredModel(source OpenapiUpdateWrapper[openapi.RegisteredModel]) (openapi.RegisteredModel, error) + + // Ignore all fields that ARE editable + // goverter:default InitModelVersionWithUpdate + // goverter:autoMap Existing + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties State + OverrideNotEditableForModelVersion(source OpenapiUpdateWrapper[openapi.ModelVersion]) (openapi.ModelVersion, error) + + // Ignore all fields that ARE editable + // goverter:default InitModelArtifactWithUpdate + // goverter:autoMap Existing + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties Uri State ServiceAccountName ModelFormatName ModelFormatVersion StorageKey StoragePath + OverrideNotEditableForModelArtifact(source OpenapiUpdateWrapper[openapi.ModelArtifact]) (openapi.ModelArtifact, error) + + // Ignore all fields that ARE editable + // goverter:default InitServingEnvironmentWithUpdate + // goverter:autoMap Existing + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties + OverrideNotEditableForServingEnvironment(source OpenapiUpdateWrapper[openapi.ServingEnvironment]) (openapi.ServingEnvironment, error) + + // Ignore all fields that ARE editable + // goverter:default InitInferenceServiceWithUpdate + // goverter:autoMap Existing + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties ModelVersionId Runtime State + OverrideNotEditableForInferenceService(source OpenapiUpdateWrapper[openapi.InferenceService]) (openapi.InferenceService, error) + + // Ignore all fields that ARE editable + // goverter:default InitServeModelWithUpdate + // goverter:autoMap Existing + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties LastKnownState + OverrideNotEditableForServeModel(source OpenapiUpdateWrapper[openapi.ServeModel]) (openapi.ServeModel, error) } diff --git a/internal/converter/openapi_converter_test.go b/internal/converter/openapi_converter_test.go new file mode 100644 index 00000000..36f256f9 --- /dev/null +++ b/internal/converter/openapi_converter_test.go @@ -0,0 +1,160 @@ +package converter + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + "os" + "reflect" + "regexp" + "strings" + "testing" + + "github.com/opendatahub-io/model-registry/pkg/openapi" +) + +// visitor +type visitor struct { + t *testing.T + entities map[string]*oapiEntity +} + +func newVisitor(t *testing.T, f *ast.File) visitor { + return visitor{ + t: t, + entities: map[string]*oapiEntity{ + "RegisteredModel": { + obj: openapi.RegisteredModel{}, + }, + "ModelVersion": { + obj: openapi.ModelVersion{}, + }, + "ModelArtifact": { + obj: openapi.ModelArtifact{}, + }, + "ServingEnvironment": { + obj: openapi.ServingEnvironment{}, + }, + "InferenceService": { + obj: openapi.InferenceService{}, + }, + "ServeModel": { + obj: openapi.ServeModel{}, + }, + }, + } +} + +func (v *visitor) extractGroup(regex *regexp.Regexp, s string) string { + extracted := regex.FindStringSubmatch(s) + if len(extracted) != 2 { + v.t.Errorf("unable to extract groups from %s for %s", regex.String(), s) + } + // the first one is the wole matched string, the second one is the group + return extracted[1] +} + +func (v *visitor) getEntity(name string) *oapiEntity { + val, ok := v.entities[name] + if !ok { + v.t.Errorf("openapi entity not found in the entities map: %s", name) + } + return val +} + +func (v visitor) Visit(n ast.Node) ast.Visitor { + if n == nil { + return nil + } + + switch d := n.(type) { + case *ast.InterfaceType: + for _, m := range d.Methods.List { + methodName := m.Names[0].Name + + if converterMethodPattern.MatchString(methodName) { + entityName := v.extractGroup(converterMethodPattern, methodName) + entity := v.getEntity(entityName) + // there should be just one doc comment matching ignoreDirectivePattern + for _, c := range m.Doc.List { + if ignoreDirectivePattern.MatchString(c.Text) { + entity.notEditableFields = v.extractGroup(ignoreDirectivePattern, c.Text) + } + } + } else if overrideNotEditableMethodPattern.MatchString(methodName) { + entityName := v.extractGroup(overrideNotEditableMethodPattern, methodName) + entity := v.getEntity(entityName) + // there should be just one doc comment matching ignoreDirectivePattern + for _, c := range m.Doc.List { + if ignoreDirectivePattern.MatchString(c.Text) { + entity.ignoredFields = v.extractGroup(ignoreDirectivePattern, c.Text) + } + } + } + } + v.checkEntities() + } + return v +} + +// checkEntities check if all editable fields are listed in the goverter ignore directive of OverrideNotEditableFor +func (v *visitor) checkEntities() { + errorMsgs := map[string][]string{} + for k, v := range v.entities { + msgs := checkEntity(v) + if len(msgs) > 0 { + errorMsgs[k] = msgs + } + } + + if len(errorMsgs) > 0 { + missingFieldsMsg := "" + for k, fields := range errorMsgs { + missingFieldsMsg += fmt.Sprintf("%s: %v\n", k, fields) + } + v.t.Errorf("missing fields to be ignored for OverrideNotEditableFor* goverter methods:\n%v", missingFieldsMsg) + } +} + +// checkEntity check if there are missing fields to be ignored in the override method +func checkEntity(entity *oapiEntity) []string { + res := []string{} + objType := reflect.TypeOf(entity.obj) + for i := 0; i < objType.NumField(); i++ { + field := objType.Field(i) + if !strings.Contains(entity.notEditableFields, field.Name) && !strings.Contains(entity.ignoredFields, field.Name) { + // check if the not editable field (first check) is not present in the ignored fields (second check) + // if this condition is true, we missed that field in the Override method ignore list + res = append(res, field.Name) + } + } + return res +} + +// test + +var converterMethodPattern *regexp.Regexp = regexp.MustCompile(`Convert(?P\w+)Update`) +var overrideNotEditableMethodPattern *regexp.Regexp = regexp.MustCompile(`OverrideNotEditableFor(?P\w+)`) +var ignoreDirectivePattern *regexp.Regexp = regexp.MustCompile(`// goverter:ignore (?P.+)`) + +func TestOverrideNotEditableFields(t *testing.T) { + _ = setup(t) + + fset := token.NewFileSet() // positions are relative to fset + wd, err := os.Getwd() + if err != nil { + t.Errorf("error getting current working directory") + } + filePath := fmt.Sprintf("%s/opeanpi_converter.go", wd) + f, _ := parser.ParseFile(fset, filePath, nil, parser.ParseComments) + + v := newVisitor(t, f) + ast.Walk(v, f) +} + +type oapiEntity struct { + obj any + notEditableFields string + ignoredFields string +} diff --git a/internal/converter/openapi_converter_util.go b/internal/converter/openapi_converter_util.go new file mode 100644 index 00000000..c82bda4a --- /dev/null +++ b/internal/converter/openapi_converter_util.go @@ -0,0 +1,71 @@ +package converter + +import "github.com/opendatahub-io/model-registry/pkg/openapi" + +type OpenapiUpdateWrapper[ + M openapi.RegisteredModel | + openapi.ModelVersion | + openapi.ModelArtifact | + openapi.ServingEnvironment | + openapi.InferenceService | + openapi.ServeModel, +] struct { + Existing *M + Update *M +} + +func NewOpenapiUpdateWrapper[ + M openapi.RegisteredModel | + openapi.ModelVersion | + openapi.ModelArtifact | + openapi.ServingEnvironment | + openapi.InferenceService | + openapi.ServeModel, +](existing *M, update *M) OpenapiUpdateWrapper[M] { + return OpenapiUpdateWrapper[M]{ + Existing: existing, + Update: update, + } +} + +func InitRegisteredModelWithUpdate(source OpenapiUpdateWrapper[openapi.RegisteredModel]) openapi.RegisteredModel { + if source.Update != nil { + return *source.Update + } + return openapi.RegisteredModel{} +} + +func InitModelVersionWithUpdate(source OpenapiUpdateWrapper[openapi.ModelVersion]) openapi.ModelVersion { + if source.Update != nil { + return *source.Update + } + return openapi.ModelVersion{} +} + +func InitModelArtifactWithUpdate(source OpenapiUpdateWrapper[openapi.ModelArtifact]) openapi.ModelArtifact { + if source.Update != nil { + return *source.Update + } + return openapi.ModelArtifact{} +} + +func InitServingEnvironmentWithUpdate(source OpenapiUpdateWrapper[openapi.ServingEnvironment]) openapi.ServingEnvironment { + if source.Update != nil { + return *source.Update + } + return openapi.ServingEnvironment{} +} + +func InitInferenceServiceWithUpdate(source OpenapiUpdateWrapper[openapi.InferenceService]) openapi.InferenceService { + if source.Update != nil { + return *source.Update + } + return openapi.InferenceService{} +} + +func InitServeModelWithUpdate(source OpenapiUpdateWrapper[openapi.ServeModel]) openapi.ServeModel { + if source.Update != nil { + return *source.Update + } + return openapi.ServeModel{} +} diff --git a/pkg/core/core.go b/pkg/core/core.go index 188ea68d..0dfce13c 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -7,6 +7,7 @@ import ( "github.com/golang/glog" "github.com/opendatahub-io/model-registry/internal/apiutils" "github.com/opendatahub-io/model-registry/internal/converter" + "github.com/opendatahub-io/model-registry/internal/converter/generated" "github.com/opendatahub-io/model-registry/internal/mapper" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/pkg/api" @@ -26,8 +27,9 @@ var ( // ModelRegistryService is the core library of the model registry type ModelRegistryService struct { - mlmdClient proto.MetadataStoreServiceClient - mapper *mapper.Mapper + mlmdClient proto.MetadataStoreServiceClient + mapper *mapper.Mapper + openapiConv *generated.OpenAPIConverterImpl } // NewModelRegistryService create a fresh instance of ModelRegistryService, taking care of setting up needed MLMD Types @@ -154,6 +156,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, inferenceServiceResp.GetTypeId(), serveModelResp.GetTypeId(), ), + openapiConv: &generated.OpenAPIConverterImpl{}, }, nil } @@ -171,13 +174,12 @@ func (serv *ModelRegistryService) UpsertRegisteredModel(registeredModel *openapi if err != nil { return nil, err } - } - // if already existing assure the name is the same - if existing != nil && registeredModel.Name == nil { - // user did not provide it - // need to set it to avoid mlmd error "context name should not be empty" - registeredModel.Name = existing.Name + withNotEditable, err := serv.openapiConv.OverrideNotEditableForRegisteredModel(converter.NewOpenapiUpdateWrapper(existing, registeredModel)) + if err != nil { + return nil, err + } + registeredModel = &withNotEditable } modelCtx, err := serv.mapper.MapFromRegisteredModel(registeredModel) @@ -365,17 +367,17 @@ func (serv *ModelRegistryService) UpsertModelVersion(modelVersion *openapi.Model if err != nil { return nil, err } - registeredModel, err = serv.getRegisteredModelByVersionId(*modelVersion.Id) + + withNotEditable, err := serv.openapiConv.OverrideNotEditableForModelVersion(converter.NewOpenapiUpdateWrapper(existing, modelVersion)) if err != nil { return nil, err } - } + modelVersion = &withNotEditable - // if already existing assure the name is the same - if existing != nil && modelVersion.Name == nil { - // user did not provide it - // need to set it to avoid mlmd error "context name should not be empty" - modelVersion.Name = existing.Name + registeredModel, err = serv.getRegisteredModelByVersionId(*modelVersion.Id) + if err != nil { + return nil, err + } } modelCtx, err := serv.mapper.MapFromModelVersion(modelVersion, *registeredModel.Id, registeredModel.Name) @@ -595,18 +597,16 @@ func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod if err != nil { return nil, err } - _, err = serv.getModelVersionByArtifactId(*modelArtifact.Id) + + withNotEditable, err := serv.openapiConv.OverrideNotEditableForModelArtifact(converter.NewOpenapiUpdateWrapper(existing, modelArtifact)) if err != nil { return nil, err } - } + modelArtifact = &withNotEditable - // if already existing assure the name is the same - if existing != nil { - if modelArtifact.Name == nil { - // user did not provide it - // need to set it to avoid mlmd error "artifact name should not be empty" - modelArtifact.Name = existing.Name + _, err = serv.getModelVersionByArtifactId(*modelArtifact.Id) + if err != nil { + return nil, err } } @@ -787,13 +787,12 @@ func (serv *ModelRegistryService) UpsertServingEnvironment(servingEnvironment *o if err != nil { return nil, err } - } - // if already existing assure the name is the same - if existing != nil && servingEnvironment.Name == nil { - // user did not provide it - // need to set it to avoid mlmd error "context name should not be empty" - servingEnvironment.Name = existing.Name + withNotEditable, err := serv.openapiConv.OverrideNotEditableForServingEnvironment(converter.NewOpenapiUpdateWrapper(existing, servingEnvironment)) + if err != nil { + return nil, err + } + servingEnvironment = &withNotEditable } protoCtx, err := serv.mapper.MapFromServingEnvironment(servingEnvironment) @@ -937,10 +936,18 @@ func (serv *ModelRegistryService) UpsertInferenceService(inferenceService *opena } else { // update glog.Infof("Updating InferenceService %s", *inferenceService.Id) + existing, err = serv.GetInferenceServiceById(*inferenceService.Id) if err != nil { return nil, err } + + withNotEditable, err := serv.openapiConv.OverrideNotEditableForInferenceService(converter.NewOpenapiUpdateWrapper(existing, inferenceService)) + if err != nil { + return nil, err + } + inferenceService = &withNotEditable + servingEnvironment, err = serv.getServingEnvironmentByInferenceServiceId(*inferenceService.Id) if err != nil { return nil, err @@ -1153,10 +1160,18 @@ func (serv *ModelRegistryService) UpsertServeModel(serveModel *openapi.ServeMode } else { // update glog.Infof("Updating ServeModel %s", *serveModel.Id) + existing, err = serv.GetServeModelById(*serveModel.Id) if err != nil { return nil, err } + + withNotEditable, err := serv.openapiConv.OverrideNotEditableForServeModel(converter.NewOpenapiUpdateWrapper(existing, serveModel)) + if err != nil { + return nil, err + } + serveModel = &withNotEditable + _, err = serv.getInferenceServiceByServeModel(*serveModel.Id) if err != nil { return nil, err diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index a4cd99a5..db4aba1e 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -2447,7 +2447,6 @@ func TestUpdateInferenceService(t *testing.T) { getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - fmt.Printf("%+v", getAllResp.Contexts) assertion.Equal(3, len(getAllResp.Contexts), "there should be 3 contexts saved in mlmd") // update with nil name @@ -2474,6 +2473,14 @@ func TestUpdateInferenceService(t *testing.T) { assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) + + // update with empty registeredModelId + newExternalId = "org.my_awesome_entity_@v1" + prevRegModelId := updatedEntity.RegisteredModelId + updatedEntity.RegisteredModelId = "" + updatedEntity, err = service.UpsertInferenceService(updatedEntity) + assertion.Nil(err) + assertion.Equal(prevRegModelId, updatedEntity.RegisteredModelId) } func TestUpdateInferenceServiceFailure(t *testing.T) { @@ -3096,6 +3103,13 @@ func TestUpdateServeModel(t *testing.T) { assertion.Equal(string(newState), getById.Executions[0].LastKnownState.String()) assertion.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) assertion.Equal(*(*createdEntity.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["author"].GetStringValue()) + + prevModelVersionId := updatedEntity.ModelVersionId + updatedEntity.ModelVersionId = "" + updatedEntity, err = service.UpsertServeModel(updatedEntity, &inferenceServiceId) + assertion.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) + assertion.Equal(prevModelVersionId, updatedEntity.ModelVersionId) + } func TestUpdateServeModelFailure(t *testing.T) { From 17dea158684eea736d50763d63454bfbf80b0d32 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:11 -0300 Subject: [PATCH 155/254] py: indicate overriden methods using typing_extensions Signed-off-by: Isabella Basso do Amaral --- clients/python/poetry.lock | 337 +++++++++--------- clients/python/pyproject.toml | 1 + .../src/model_registry/types/artifacts.py | 7 + .../python/src/model_registry/types/base.py | 15 +- .../src/model_registry/types/contexts.py | 9 +- 5 files changed, 199 insertions(+), 170 deletions(-) diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock index 9431ea5e..5baa77ea 100644 --- a/clients/python/poetry.lock +++ b/clients/python/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. [[package]] name = "absl-py" @@ -73,112 +73,112 @@ lxml = ["lxml"] [[package]] name = "certifi" -version = "2023.7.22" +version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, + {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, + {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, ] [[package]] name = "charset-normalizer" -version = "3.3.1" +version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.3.1.tar.gz", hash = "sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-win32.whl", hash = "sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f"}, - {file = "charset_normalizer-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-win32.whl", hash = "sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8"}, - {file = "charset_normalizer-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-win32.whl", hash = "sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61"}, - {file = "charset_normalizer-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63a6f59e2d01310f754c270e4a257426fe5a591dc487f1983b3bbe793cf6bac6"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d6bfc32a68bc0933819cfdfe45f9abc3cae3877e1d90aac7259d57e6e0f85b1"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f3100d86dcd03c03f7e9c3fdb23d92e32abbca07e7c13ebd7ddfbcb06f5991f"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39b70a6f88eebe239fa775190796d55a33cfb6d36b9ffdd37843f7c4c1b5dc67"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e12f8ee80aa35e746230a2af83e81bd6b52daa92a8afaef4fea4a2ce9b9f4fa"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b6cefa579e1237ce198619b76eaa148b71894fb0d6bcf9024460f9bf30fd228"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:61f1e3fb621f5420523abb71f5771a204b33c21d31e7d9d86881b2cffe92c47c"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:4f6e2a839f83a6a76854d12dbebde50e4b1afa63e27761549d006fa53e9aa80e"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:1ec937546cad86d0dce5396748bf392bb7b62a9eeb8c66efac60e947697f0e58"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:82ca51ff0fc5b641a2d4e1cc8c5ff108699b7a56d7f3ad6f6da9dbb6f0145b48"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:633968254f8d421e70f91c6ebe71ed0ab140220469cf87a9857e21c16687c034"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-win32.whl", hash = "sha256:c0c72d34e7de5604df0fde3644cc079feee5e55464967d10b24b1de268deceb9"}, - {file = "charset_normalizer-3.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:63accd11149c0f9a99e3bc095bbdb5a464862d77a7e309ad5938fbc8721235ae"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5a3580a4fdc4ac05f9e53c57f965e3594b2f99796231380adb2baaab96e22761"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2465aa50c9299d615d757c1c888bc6fef384b7c4aec81c05a0172b4400f98557"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cb7cd68814308aade9d0c93c5bd2ade9f9441666f8ba5aa9c2d4b389cb5e2a45"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e43805ccafa0a91831f9cd5443aa34528c0c3f2cc48c4cb3d9a7721053874b"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:854cc74367180beb327ab9d00f964f6d91da06450b0855cbbb09187bcdb02de5"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c15070ebf11b8b7fd1bfff7217e9324963c82dbdf6182ff7050519e350e7ad9f"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4c99f98fc3a1835af8179dcc9013f93594d0670e2fa80c83aa36346ee763d2"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fb765362688821404ad6cf86772fc54993ec11577cd5a92ac44b4c2ba52155b"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dced27917823df984fe0c80a5c4ad75cf58df0fbfae890bc08004cd3888922a2"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a66bcdf19c1a523e41b8e9d53d0cedbfbac2e93c649a2e9502cb26c014d0980c"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ecd26be9f112c4f96718290c10f4caea6cc798459a3a76636b817a0ed7874e42"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f70fd716855cd3b855316b226a1ac8bdb3caf4f7ea96edcccc6f484217c9597"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:17a866d61259c7de1bdadef418a37755050ddb4b922df8b356503234fff7932c"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-win32.whl", hash = "sha256:548eefad783ed787b38cb6f9a574bd8664468cc76d1538215d510a3cd41406cb"}, - {file = "charset_normalizer-3.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:45f053a0ece92c734d874861ffe6e3cc92150e32136dd59ab1fb070575189c97"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-win32.whl", hash = "sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4"}, - {file = "charset_normalizer-3.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727"}, - {file = "charset_normalizer-3.3.1-py3-none-any.whl", hash = "sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708"}, + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, ] [[package]] @@ -272,13 +272,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.1.3" +version = "1.2.0" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, - {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, ] [package.extras] @@ -303,69 +303,69 @@ sphinx-basic-ng = "*" [[package]] name = "grpcio" -version = "1.59.0" +version = "1.59.3" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.7" files = [ - {file = "grpcio-1.59.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:225e5fa61c35eeaebb4e7491cd2d768cd8eb6ed00f2664fa83a58f29418b39fd"}, - {file = "grpcio-1.59.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:b95ec8ecc4f703f5caaa8d96e93e40c7f589bad299a2617bdb8becbcce525539"}, - {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:1a839ba86764cc48226f50b924216000c79779c563a301586a107bda9cbe9dcf"}, - {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6cfe44a5d7c7d5f1017a7da1c8160304091ca5dc64a0f85bca0d63008c3137a"}, - {file = "grpcio-1.59.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0fcf53df684fcc0154b1e61f6b4a8c4cf5f49d98a63511e3f30966feff39cd0"}, - {file = "grpcio-1.59.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa66cac32861500f280bb60fe7d5b3e22d68c51e18e65367e38f8669b78cea3b"}, - {file = "grpcio-1.59.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8cd2d38c2d52f607d75a74143113174c36d8a416d9472415eab834f837580cf7"}, - {file = "grpcio-1.59.0-cp310-cp310-win32.whl", hash = "sha256:228b91ce454876d7eed74041aff24a8f04c0306b7250a2da99d35dd25e2a1211"}, - {file = "grpcio-1.59.0-cp310-cp310-win_amd64.whl", hash = "sha256:ca87ee6183421b7cea3544190061f6c1c3dfc959e0b57a5286b108511fd34ff4"}, - {file = "grpcio-1.59.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:c173a87d622ea074ce79be33b952f0b424fa92182063c3bda8625c11d3585d09"}, - {file = "grpcio-1.59.0-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:ec78aebb9b6771d6a1de7b6ca2f779a2f6113b9108d486e904bde323d51f5589"}, - {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:0b84445fa94d59e6806c10266b977f92fa997db3585f125d6b751af02ff8b9fe"}, - {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c251d22de8f9f5cca9ee47e4bade7c5c853e6e40743f47f5cc02288ee7a87252"}, - {file = "grpcio-1.59.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:956f0b7cb465a65de1bd90d5a7475b4dc55089b25042fe0f6c870707e9aabb1d"}, - {file = "grpcio-1.59.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:38da5310ef84e16d638ad89550b5b9424df508fd5c7b968b90eb9629ca9be4b9"}, - {file = "grpcio-1.59.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:63982150a7d598281fa1d7ffead6096e543ff8be189d3235dd2b5604f2c553e5"}, - {file = "grpcio-1.59.0-cp311-cp311-win32.whl", hash = "sha256:50eff97397e29eeee5df106ea1afce3ee134d567aa2c8e04fabab05c79d791a7"}, - {file = "grpcio-1.59.0-cp311-cp311-win_amd64.whl", hash = "sha256:15f03bd714f987d48ae57fe092cf81960ae36da4e520e729392a59a75cda4f29"}, - {file = "grpcio-1.59.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:f1feb034321ae2f718172d86b8276c03599846dc7bb1792ae370af02718f91c5"}, - {file = "grpcio-1.59.0-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:d09bd2a4e9f5a44d36bb8684f284835c14d30c22d8ec92ce796655af12163588"}, - {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:2f120d27051e4c59db2f267b71b833796770d3ea36ca712befa8c5fff5da6ebd"}, - {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0ca727a173ee093f49ead932c051af463258b4b493b956a2c099696f38aa66"}, - {file = "grpcio-1.59.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5711c51e204dc52065f4a3327dca46e69636a0b76d3e98c2c28c4ccef9b04c52"}, - {file = "grpcio-1.59.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:d74f7d2d7c242a6af9d4d069552ec3669965b74fed6b92946e0e13b4168374f9"}, - {file = "grpcio-1.59.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3859917de234a0a2a52132489c4425a73669de9c458b01c9a83687f1f31b5b10"}, - {file = "grpcio-1.59.0-cp312-cp312-win32.whl", hash = "sha256:de2599985b7c1b4ce7526e15c969d66b93687571aa008ca749d6235d056b7205"}, - {file = "grpcio-1.59.0-cp312-cp312-win_amd64.whl", hash = "sha256:598f3530231cf10ae03f4ab92d48c3be1fee0c52213a1d5958df1a90957e6a88"}, - {file = "grpcio-1.59.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:b34c7a4c31841a2ea27246a05eed8a80c319bfc0d3e644412ec9ce437105ff6c"}, - {file = "grpcio-1.59.0-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:c4dfdb49f4997dc664f30116af2d34751b91aa031f8c8ee251ce4dcfc11277b0"}, - {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:61bc72a00ecc2b79d9695220b4d02e8ba53b702b42411397e831c9b0589f08a3"}, - {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f367e4b524cb319e50acbdea57bb63c3b717c5d561974ace0b065a648bb3bad3"}, - {file = "grpcio-1.59.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:849c47ef42424c86af069a9c5e691a765e304079755d5c29eff511263fad9c2a"}, - {file = "grpcio-1.59.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c0488c2b0528e6072010182075615620071371701733c63ab5be49140ed8f7f0"}, - {file = "grpcio-1.59.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:611d9aa0017fa386809bddcb76653a5ab18c264faf4d9ff35cb904d44745f575"}, - {file = "grpcio-1.59.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e5378785dce2b91eb2e5b857ec7602305a3b5cf78311767146464bfa365fc897"}, - {file = "grpcio-1.59.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:fe976910de34d21057bcb53b2c5e667843588b48bf11339da2a75f5c4c5b4055"}, - {file = "grpcio-1.59.0-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:c041a91712bf23b2a910f61e16565a05869e505dc5a5c025d429ca6de5de842c"}, - {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:0ae444221b2c16d8211b55326f8ba173ba8f8c76349bfc1768198ba592b58f74"}, - {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ceb1e68135788c3fce2211de86a7597591f0b9a0d2bb80e8401fd1d915991bac"}, - {file = "grpcio-1.59.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c4b1cc3a9dc1924d2eb26eec8792fedd4b3fcd10111e26c1d551f2e4eda79ce"}, - {file = "grpcio-1.59.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:871371ce0c0055d3db2a86fdebd1e1d647cf21a8912acc30052660297a5a6901"}, - {file = "grpcio-1.59.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:93e9cb546e610829e462147ce724a9cb108e61647a3454500438a6deef610be1"}, - {file = "grpcio-1.59.0-cp38-cp38-win32.whl", hash = "sha256:f21917aa50b40842b51aff2de6ebf9e2f6af3fe0971c31960ad6a3a2b24988f4"}, - {file = "grpcio-1.59.0-cp38-cp38-win_amd64.whl", hash = "sha256:14890da86a0c0e9dc1ea8e90101d7a3e0e7b1e71f4487fab36e2bfd2ecadd13c"}, - {file = "grpcio-1.59.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:34341d9e81a4b669a5f5dca3b2a760b6798e95cdda2b173e65d29d0b16692857"}, - {file = "grpcio-1.59.0-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:986de4aa75646e963466b386a8c5055c8b23a26a36a6c99052385d6fe8aaf180"}, - {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:aca8a24fef80bef73f83eb8153f5f5a0134d9539b4c436a716256b311dda90a6"}, - {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:936b2e04663660c600d5173bc2cc84e15adbad9c8f71946eb833b0afc205b996"}, - {file = "grpcio-1.59.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc8bf2e7bc725e76c0c11e474634a08c8f24bcf7426c0c6d60c8f9c6e70e4d4a"}, - {file = "grpcio-1.59.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81d86a096ccd24a57fa5772a544c9e566218bc4de49e8c909882dae9d73392df"}, - {file = "grpcio-1.59.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2ea95cd6abbe20138b8df965b4a8674ec312aaef3147c0f46a0bac661f09e8d0"}, - {file = "grpcio-1.59.0-cp39-cp39-win32.whl", hash = "sha256:3b8ff795d35a93d1df6531f31c1502673d1cebeeba93d0f9bd74617381507e3f"}, - {file = "grpcio-1.59.0-cp39-cp39-win_amd64.whl", hash = "sha256:38823bd088c69f59966f594d087d3a929d1ef310506bee9e3648317660d65b81"}, - {file = "grpcio-1.59.0.tar.gz", hash = "sha256:acf70a63cf09dd494000007b798aff88a436e1c03b394995ce450be437b8e54f"}, + {file = "grpcio-1.59.3-cp310-cp310-linux_armv7l.whl", hash = "sha256:aca028a6c7806e5b61e5f9f4232432c52856f7fcb98e330b20b6bc95d657bdcc"}, + {file = "grpcio-1.59.3-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:19ad26a7967f7999c8960d2b9fe382dae74c55b0c508c613a6c2ba21cddf2354"}, + {file = "grpcio-1.59.3-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:72b71dad2a3d1650e69ad42a5c4edbc59ee017f08c32c95694172bc501def23c"}, + {file = "grpcio-1.59.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c0f0a11d82d0253656cc42e04b6a149521e02e755fe2e4edd21123de610fd1d4"}, + {file = "grpcio-1.59.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60cddafb70f9a2c81ba251b53b4007e07cca7389e704f86266e22c4bffd8bf1d"}, + {file = "grpcio-1.59.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6c75a1fa0e677c1d2b6d4196ad395a5c381dfb8385f07ed034ef667cdcdbcc25"}, + {file = "grpcio-1.59.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e1d8e01438d5964a11167eec1edb5f85ed8e475648f36c834ed5db4ffba24ac8"}, + {file = "grpcio-1.59.3-cp310-cp310-win32.whl", hash = "sha256:c4b0076f0bf29ee62335b055a9599f52000b7941f577daa001c7ef961a1fbeab"}, + {file = "grpcio-1.59.3-cp310-cp310-win_amd64.whl", hash = "sha256:b1f00a3e6e0c3dccccffb5579fc76ebfe4eb40405ba308505b41ef92f747746a"}, + {file = "grpcio-1.59.3-cp311-cp311-linux_armv7l.whl", hash = "sha256:3996aaa21231451161dc29df6a43fcaa8b332042b6150482c119a678d007dd86"}, + {file = "grpcio-1.59.3-cp311-cp311-macosx_10_10_universal2.whl", hash = "sha256:cb4e9cbd9b7388fcb06412da9f188c7803742d06d6f626304eb838d1707ec7e3"}, + {file = "grpcio-1.59.3-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:8022ca303d6c694a0d7acfb2b472add920217618d3a99eb4b14edc7c6a7e8fcf"}, + {file = "grpcio-1.59.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b36683fad5664283755a7f4e2e804e243633634e93cd798a46247b8e54e3cb0d"}, + {file = "grpcio-1.59.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8239b853226e4824e769517e1b5232e7c4dda3815b200534500338960fcc6118"}, + {file = "grpcio-1.59.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0511af8653fbda489ff11d542a08505d56023e63cafbda60e6e00d4e0bae86ea"}, + {file = "grpcio-1.59.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e78dc982bda74cef2ddfce1c91d29b96864c4c680c634e279ed204d51e227473"}, + {file = "grpcio-1.59.3-cp311-cp311-win32.whl", hash = "sha256:6a5c3a96405966c023e139c3bcccb2c7c776a6f256ac6d70f8558c9041bdccc3"}, + {file = "grpcio-1.59.3-cp311-cp311-win_amd64.whl", hash = "sha256:ed26826ee423b11477297b187371cdf4fa1eca874eb1156422ef3c9a60590dd9"}, + {file = "grpcio-1.59.3-cp312-cp312-linux_armv7l.whl", hash = "sha256:45dddc5cb5227d30fa43652d8872dc87f086d81ab4b500be99413bad0ae198d7"}, + {file = "grpcio-1.59.3-cp312-cp312-macosx_10_10_universal2.whl", hash = "sha256:1736496d74682e53dd0907fd515f2694d8e6a96c9a359b4080b2504bf2b2d91b"}, + {file = "grpcio-1.59.3-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:ddbd1a16138e52e66229047624de364f88a948a4d92ba20e4e25ad7d22eef025"}, + {file = "grpcio-1.59.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcfa56f8d031ffda902c258c84c4b88707f3a4be4827b4e3ab8ec7c24676320d"}, + {file = "grpcio-1.59.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2eb8f0c7c0c62f7a547ad7a91ba627a5aa32a5ae8d930783f7ee61680d7eb8d"}, + {file = "grpcio-1.59.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8d993399cc65e3a34f8fd48dd9ad7a376734564b822e0160dd18b3d00c1a33f9"}, + {file = "grpcio-1.59.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0bd141f4f41907eb90bda74d969c3cb21c1c62779419782a5b3f5e4b5835718"}, + {file = "grpcio-1.59.3-cp312-cp312-win32.whl", hash = "sha256:33b8fd65d4e97efa62baec6171ce51f9cf68f3a8ba9f866f4abc9d62b5c97b79"}, + {file = "grpcio-1.59.3-cp312-cp312-win_amd64.whl", hash = "sha256:0e735ed002f50d4f3cb9ecfe8ac82403f5d842d274c92d99db64cfc998515e07"}, + {file = "grpcio-1.59.3-cp37-cp37m-linux_armv7l.whl", hash = "sha256:ea40ce4404e7cca0724c91a7404da410f0144148fdd58402a5942971e3469b94"}, + {file = "grpcio-1.59.3-cp37-cp37m-macosx_10_10_universal2.whl", hash = "sha256:83113bcc393477b6f7342b9f48e8a054330c895205517edc66789ceea0796b53"}, + {file = "grpcio-1.59.3-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:73afbac602b8f1212a50088193601f869b5073efa9855b3e51aaaec97848fc8a"}, + {file = "grpcio-1.59.3-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:575d61de1950b0b0699917b686b1ca108690702fcc2df127b8c9c9320f93e069"}, + {file = "grpcio-1.59.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd76057b5c9a4d68814610ef9226925f94c1231bbe533fdf96f6181f7d2ff9e"}, + {file = "grpcio-1.59.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:95d6fd804c81efe4879e38bfd84d2b26e339a0a9b797e7615e884ef4686eb47b"}, + {file = "grpcio-1.59.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0d42048b8a3286ea4134faddf1f9a59cf98192b94aaa10d910a25613c5eb5bfb"}, + {file = "grpcio-1.59.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4619fea15c64bcdd9d447cdbdde40e3d5f1da3a2e8ae84103d94a9c1df210d7e"}, + {file = "grpcio-1.59.3-cp38-cp38-linux_armv7l.whl", hash = "sha256:95b5506e70284ac03b2005dd9ffcb6708c9ae660669376f0192a710687a22556"}, + {file = "grpcio-1.59.3-cp38-cp38-macosx_10_10_universal2.whl", hash = "sha256:9e17660947660ccfce56c7869032910c179a5328a77b73b37305cd1ee9301c2e"}, + {file = "grpcio-1.59.3-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:00912ce19914d038851be5cd380d94a03f9d195643c28e3ad03d355cc02ce7e8"}, + {file = "grpcio-1.59.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e58b3cadaa3c90f1efca26ba33e0d408b35b497307027d3d707e4bcd8de862a6"}, + {file = "grpcio-1.59.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d787ecadea865bdf78f6679f6f5bf4b984f18f659257ba612979df97a298b3c3"}, + {file = "grpcio-1.59.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0814942ba1bba269db4e760a34388640c601dece525c6a01f3b4ff030cc0db69"}, + {file = "grpcio-1.59.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fb111aa99d3180c361a35b5ae1e2c63750220c584a1344229abc139d5c891881"}, + {file = "grpcio-1.59.3-cp38-cp38-win32.whl", hash = "sha256:eb8ba504c726befe40a356ecbe63c6c3c64c9a439b3164f5a718ec53c9874da0"}, + {file = "grpcio-1.59.3-cp38-cp38-win_amd64.whl", hash = "sha256:cdbc6b32fadab9bebc6f49d3e7ec4c70983c71e965497adab7f87de218e84391"}, + {file = "grpcio-1.59.3-cp39-cp39-linux_armv7l.whl", hash = "sha256:c82ca1e4be24a98a253d6dbaa216542e4163f33f38163fc77964b0f0d255b552"}, + {file = "grpcio-1.59.3-cp39-cp39-macosx_10_10_universal2.whl", hash = "sha256:36636babfda14f9e9687f28d5b66d349cf88c1301154dc71c6513de2b6c88c59"}, + {file = "grpcio-1.59.3-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5f9b2e591da751ac7fdd316cc25afafb7a626dededa9b414f90faad7f3ccebdb"}, + {file = "grpcio-1.59.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a93a82876a4926bf451db82ceb725bd87f42292bacc94586045261f501a86994"}, + {file = "grpcio-1.59.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce31fa0bfdd1f2bb15b657c16105c8652186eab304eb512e6ae3b99b2fdd7d13"}, + {file = "grpcio-1.59.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:16da0e40573962dab6cba16bec31f25a4f468e6d05b658e589090fe103b03e3d"}, + {file = "grpcio-1.59.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d1a17372fd425addd5812049fa7374008ffe689585f27f802d0935522cf4b7"}, + {file = "grpcio-1.59.3-cp39-cp39-win32.whl", hash = "sha256:52cc38a7241b5f7b4a91aaf9000fdd38e26bb00d5e8a71665ce40cfcee716281"}, + {file = "grpcio-1.59.3-cp39-cp39-win_amd64.whl", hash = "sha256:b491e5bbcad3020a96842040421e508780cade35baba30f402df9d321d1c423e"}, + {file = "grpcio-1.59.3.tar.gz", hash = "sha256:7800f99568a74a06ebdccd419dd1b6e639b477dcaf6da77ea702f8fb14ce5f80"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.59.0)"] +protobuf = ["grpcio-tools (>=1.59.3)"] [[package]] name = "idna" @@ -690,17 +690,18 @@ files = [ [[package]] name = "pygments" -version = "2.16.1" +version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.7" files = [ - {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"}, - {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"}, + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, ] [package.extras] plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] [[package]] name = "pytest" @@ -1022,6 +1023,17 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "typing-extensions" +version = "4.8.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"}, + {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, +] + [[package]] name = "uc-micro-py" version = "1.0.2" @@ -1038,18 +1050,17 @@ test = ["coverage", "pytest", "pytest-cov"] [[package]] name = "urllib3" -version = "2.0.7" +version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, - {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, + {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"}, + {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"}, ] [package.extras] brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] @@ -1071,4 +1082,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 3.11" -content-hash = "120f01d7fd8f17f2842c07f85587821f07a0aafdda13efdf91393253b69b0cae" +content-hash = "108d2d20b2ce4fe532e658c9ec604ed693f37e15b84400753949729a9cf9a3ba" diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 24792ba9..bfa7223d 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -10,6 +10,7 @@ readme = "README.md" python = ">= 3.9, < 3.11" attrs = "^21.0" ml-metadata = "^1.14.0" +typing-extensions = "^4.8" [tool.poetry.group.dev.dependencies] sphinx = "^7.2.6" diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index ec349922..dc6ffa14 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -18,6 +18,7 @@ from attrs import define, field from ml_metadata.proto import Artifact +from typing_extensions import override from .base import Prefixable, ProtoBase @@ -50,9 +51,11 @@ class BaseArtifact(ProtoBase): state: ArtifactState = field(init=False, default=ArtifactState.UNKNOWN) @classmethod + @override def get_proto_type(cls) -> type[Artifact]: return Artifact + @override def map(self) -> Artifact: mlmd_obj = super().map() mlmd_obj.uri = self.uri @@ -60,6 +63,7 @@ def map(self) -> Artifact: return mlmd_obj @classmethod + @override def unmap(cls, mlmd_obj: Artifact) -> BaseArtifact: py_obj = super().unmap(mlmd_obj) assert isinstance( @@ -96,12 +100,14 @@ class ModelArtifact(BaseArtifact, Prefixable): _model_version_id: Optional[str] = field(init=False, default=None) @property + @override def mlmd_name_prefix(self) -> str: if self._model_version_id: return self._model_version_id else: return uuid4().hex + @override def map(self) -> Artifact: mlmd_obj = super().map() props = { @@ -114,6 +120,7 @@ def map(self) -> Artifact: self._map_props(props, mlmd_obj.properties) return mlmd_obj + @override @classmethod def unmap(cls, mlmd_obj: Artifact) -> ModelArtifact: py_obj = super().unmap(mlmd_obj) diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index 3392577a..fc8519cd 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -8,6 +8,7 @@ from typing import Any, ClassVar, Optional from attrs import define, field +from typing_extensions import override from model_registry.store import ProtoType, ScalarType @@ -27,8 +28,7 @@ def get_proto_type_name(cls) -> str: @property @abstractmethod def proto_name(self) -> str: - """Name of the proto object. - """ + """Name of the proto object.""" pass @abstractmethod @@ -60,11 +60,11 @@ class Prefixable(ABC): We use prefixes to ensure that the user can insert more than one instance of the same type with the same name/external_id. """ + @property @abstractmethod def mlmd_name_prefix(self) -> str: - """Prefix to be used in the proto object. - """ + """Prefix to be used in the proto object.""" pass @@ -112,6 +112,7 @@ def get_subclass(cls, proto_type_name: str) -> Mappable: return cls._types_map[proto_type_name] @property + @override def proto_name(self) -> str: if isinstance(self, Prefixable): return f"{self.mlmd_name_prefix}:{self.name}" @@ -152,6 +153,7 @@ def _map_props( else: raise Exception(f"Unsupported type: {type(value)}") + @override def map(self) -> ProtoType: mlmd_obj = (self.get_proto_type())() mlmd_obj.name = self.proto_name @@ -190,13 +192,14 @@ def _unmap_props(mlmd_props: dict[str, Any]) -> dict[str, ScalarType]: return py_props @classmethod + @override def unmap(cls, mlmd_obj: ProtoType) -> ProtoBase: py_obj = cls.__new__(cls) py_obj.id = str(mlmd_obj.id) if isinstance(py_obj, Prefixable): name: str = mlmd_obj.name - assert ':' in name, f"Expected {name} to be prefixed" - py_obj.name = name.split(':', 1)[1] + assert ":" in name, f"Expected {name} to be prefixed" + py_obj.name = name.split(":", 1)[1] else: py_obj.name = mlmd_obj.name py_obj.description = mlmd_obj.properties["description"].string_value diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 277c5b3f..78c39eec 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -16,6 +16,7 @@ from attrs import define, field from ml_metadata.proto import Context +from typing_extensions import override from model_registry.store import ScalarType @@ -28,6 +29,7 @@ class BaseContext(ProtoBase, ABC): """Abstract base class for all contexts.""" @classmethod + @override def get_proto_type(cls) -> type[Context]: return Context @@ -60,10 +62,14 @@ def __attrs_post_init__(self) -> None: self.name = self.version @property + @override def mlmd_name_prefix(self): - assert self._registered_model_id is not None, "There's no registered model associated with this version" + assert ( + self._registered_model_id is not None + ), "There's no registered model associated with this version" return self._registered_model_id + @override def map(self) -> Context: mlmd_obj = super().map() # this should match the name of the registered model @@ -75,6 +81,7 @@ def map(self) -> Context: return mlmd_obj @classmethod + @override def unmap(cls, mlmd_obj: Context) -> ModelVersion: py_obj = super().unmap(mlmd_obj) assert isinstance( From 965733a57ae680c1a1df9961503b6643c032f0d8 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:14 -0300 Subject: [PATCH 156/254] py: client: get rid of _unmap helper As the store wrapper guarantees we have the correct instance we're looking for, unmap classes directly. This makes _types_map obsolete, and we don't need assertions after unmapping anymore. Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/client.py | 92 +++++-------------- .../python/src/model_registry/types/base.py | 27 +----- .../src/model_registry/types/contexts.py | 9 ++ 3 files changed, 35 insertions(+), 93 deletions(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 6a970303..ddebc98d 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -3,14 +3,12 @@ from collections.abc import Sequence from typing import Optional -from ml_metadata.proto import Artifact, Context, MetadataStoreClientConfig +from ml_metadata.proto import MetadataStoreClientConfig from .exceptions import StoreException from .store import ProtoType, MLMDStore from .types import ModelArtifact, ModelVersion, RegisteredModel, ListOptions -from .types.artifacts import BaseArtifact from .types.base import Mappable -from .types.contexts import BaseContext from .types.options import MLMDListOptions @@ -62,29 +60,6 @@ def _map(self, py_obj: Mappable) -> ProtoType: ) return proto_obj - def _unmap(self, proto_obj: ProtoType) -> Mappable: - """Map a proto object to a Python object. - - Helper around the `unmap` method, fetches the correct Python type to use. - - Args: - proto_obj (ProtoType): Proto object. - - Returns: - Mappable: Python object. - """ - type_name = proto_obj.type - try: - if isinstance(proto_obj, Artifact): - py_type = BaseArtifact.get_subclass(type_name) - elif isinstance(proto_obj, Context): - py_type = BaseContext.get_subclass(type_name) - else: - raise StoreException(f"Unknown proto type: {type_name}") - except Exception: - raise - return py_type.unmap(proto_obj) - def upsert_registered_model(self, registered_model: RegisteredModel) -> str: """Upsert a registered model. @@ -99,11 +74,10 @@ def upsert_registered_model(self, registered_model: RegisteredModel) -> str: """ proto_obj = self._map(registered_model) id = self._store.put_context(proto_obj) - new_py_rm = self._unmap( + new_py_rm = RegisteredModel.unmap( self._store.get_context(RegisteredModel.get_proto_type_name(), id) ) id = str(id) - assert isinstance(new_py_rm, RegisteredModel), "Expected a registered model" registered_model.id = id registered_model.create_time_since_epoch = new_py_rm.create_time_since_epoch registered_model.last_update_time_since_epoch = ( @@ -120,11 +94,9 @@ def get_registered_model_by_id(self, id: str) -> RegisteredModel: Returns: RegisteredModel: Registered model. """ - proto_rm = self._store.get_context( - RegisteredModel.get_proto_type_name(), id=int(id) + py_rm = RegisteredModel.unmap( + self._store.get_context(RegisteredModel.get_proto_type_name(), id=int(id)) ) - py_rm = self._unmap(proto_rm) - assert isinstance(py_rm, RegisteredModel), "Expected a registered model" versions = self.get_model_versions(id) assert isinstance(versions, list), "Expected a list" py_rm.versions = versions @@ -144,11 +116,13 @@ def get_registered_model_by_params( """ if name is None and external_id is None: raise StoreException("Either name or external_id must be provided") - proto_rm = self._store.get_context( - RegisteredModel.get_proto_type_name(), name=name, external_id=external_id + py_rm = RegisteredModel.unmap( + self._store.get_context( + RegisteredModel.get_proto_type_name(), + name=name, + external_id=external_id, + ) ) - py_rm = self._unmap(proto_rm) - assert isinstance(py_rm, RegisteredModel), "Expected a registered model" assert py_rm.id is not None versions = self.get_model_versions(py_rm.id) assert isinstance(versions, list), "Expected a list" @@ -170,14 +144,7 @@ def get_registered_models( proto_rms = self._store.get_contexts( RegisteredModel.get_proto_type_name(), mlmd_options ) - # using a list comprehension will generate a warning as it can't infer the type for every - # element on the list - py_rms: list[RegisteredModel] = [] - for proto_rm in proto_rms: - py_rm = self._unmap(proto_rm) - assert isinstance(py_rm, RegisteredModel), "Expected a registered model" - py_rms.append(py_rm) - return py_rms + return [RegisteredModel.unmap(proto_rm) for proto_rm in proto_rms] def upsert_model_version( self, model_version: ModelVersion, registered_model_id: str @@ -200,10 +167,9 @@ def upsert_model_version( proto_mv = self._map(model_version) id = self._store.put_context(proto_mv) self._store.put_context_parent(rm_id, id) - new_py_mv = self._unmap( + new_py_mv = ModelVersion.unmap( self._store.get_context(ModelVersion.get_proto_type_name(), id) ) - assert isinstance(new_py_mv, ModelVersion), "Expected a model version" id = str(id) model_version.id = id model_version.create_time_since_epoch = new_py_mv.create_time_since_epoch @@ -221,11 +187,11 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: Returns: ModelVersion: Model version. """ - proto_mv = self._store.get_context( - ModelVersion.get_proto_type_name(), id=int(model_version_id) + py_mv = ModelVersion.unmap( + self._store.get_context( + ModelVersion.get_proto_type_name(), id=int(model_version_id) + ) ) - py_mv = self._unmap(proto_mv) - assert isinstance(py_mv, ModelVersion), "Expected a model version" py_mv.model = self.get_model_artifact_by_params( model_version_id=model_version_id ) @@ -250,8 +216,7 @@ def get_model_versions( ) py_mvs: list[ModelVersion] = [] for proto_mv in proto_mvs: - py_mv = self._unmap(proto_mv) - assert isinstance(py_mv, ModelVersion), "Expected a model version" + py_mv = ModelVersion.unmap(proto_mv) assert py_mv.id is not None, "Model version ID is None" py_mv.model = self.get_model_artifact_by_params(model_version_id=py_mv.id) py_mvs.append(py_mv) @@ -288,8 +253,7 @@ def get_model_version_by_params( ModelVersion.get_proto_type_name(), name=f"{registered_model_id}:{version}", ) - py_mv = self._unmap(proto_mv) - assert isinstance(py_mv, ModelVersion), "Expected a model version" + py_mv = ModelVersion.unmap(proto_mv) py_mv.model = self.get_model_artifact_by_params(model_version_id=py_mv.id) return py_mv @@ -323,10 +287,9 @@ def upsert_model_artifact( proto_ma = self._map(model_artifact) id = self._store.put_artifact(proto_ma) self._store.put_attribution(mv_id, id) - new_py_ma = self._unmap( + new_py_ma = ModelArtifact.unmap( self._store.get_artifact(ModelArtifact.get_proto_type_name(), id) ) - assert isinstance(new_py_ma, ModelArtifact), "Expected a model artifact" id = str(id) model_artifact.id = id model_artifact.create_time_since_epoch = new_py_ma.create_time_since_epoch @@ -347,9 +310,7 @@ def get_model_artifact_by_id(self, id: str) -> ModelArtifact: proto_ma = self._store.get_artifact( ModelArtifact.get_proto_type_name(), int(id) ) - py_ma = self._unmap(proto_ma) - assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" - return py_ma + return ModelArtifact.unmap(proto_ma) def get_model_artifact_by_params( self, model_version_id: Optional[str] = None, external_id: Optional[str] = None @@ -375,9 +336,7 @@ def get_model_artifact_by_params( proto_ma = self._store.get_attributed_artifact( ModelArtifact.get_proto_type_name(), int(model_version_id) ) - py_ma = self._unmap(proto_ma) - assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" - return py_ma + return ModelArtifact.unmap(proto_ma) def get_model_artifacts( self, @@ -400,11 +359,4 @@ def get_model_artifacts( proto_mas = self._store.get_artifacts( ModelArtifact.get_proto_type_name(), mlmd_options ) - # using a list comprehension will generate a warning as it can't infer the type for every - # element on the list - py_mas: list[ModelArtifact] = [] - for proto_ma in proto_mas: - py_ma = self._unmap(proto_ma) - assert isinstance(py_ma, ModelArtifact), "Expected a model artifact" - py_mas.append(py_ma) - return py_mas + return [ModelArtifact.unmap(proto_ma) for proto_ma in proto_mas] diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index fc8519cd..1da9a474 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -4,8 +4,7 @@ from abc import ABC, abstractmethod from collections.abc import Mapping -from inspect import isabstract -from typing import Any, ClassVar, Optional +from typing import Any, Optional, TypeVar from attrs import define, field from typing_extensions import override @@ -91,26 +90,6 @@ class ProtoBase(Mappable, ABC): create_time_since_epoch: Optional[int] = field(init=False, default=None) last_update_time_since_epoch: Optional[int] = field(init=False, default=None) - _types_map: ClassVar[dict[str, ProtoBase]] = {} - - def __init_subclass__(cls): - super().__init_subclass__() - if isabstract(cls): - return - cls._types_map[cls.get_proto_type_name()] = cls - - @classmethod - def get_subclass(cls, proto_type_name: str) -> Mappable: - """Get a subclass by proto type name. - - Args: - proto_type_name (str): Name of the proto type. - - Returns: - Mappable: Subclass. - """ - return cls._types_map[proto_type_name] - @property @override def proto_name(self) -> str: @@ -191,9 +170,11 @@ def _unmap_props(mlmd_props: dict[str, Any]) -> dict[str, ScalarType]: return py_props + T = TypeVar("T", bound="ProtoBase") + @classmethod @override - def unmap(cls, mlmd_obj: ProtoType) -> ProtoBase: + def unmap(cls: type[T], mlmd_obj: ProtoType) -> T: py_obj = cls.__new__(cls) py_obj.id = str(mlmd_obj.id) if isinstance(py_obj, Prefixable): diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 78c39eec..69a79466 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -110,3 +110,12 @@ class RegisteredModel(BaseContext): name: str versions: list[ModelVersion] = field(init=False, factory=list) + + @classmethod + @override + def unmap(cls, mlmd_obj: Context) -> RegisteredModel: + py_obj = super().unmap(mlmd_obj) + assert isinstance( + py_obj, RegisteredModel + ), f"Expected RegisteredModel, got {type(py_obj)}" + return py_obj From 7b31d6bfcd7f98c2ce6b15bee87772fdae208a57 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:14 -0300 Subject: [PATCH 157/254] py: require type_id when mapping Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/client.py | 20 +++++++----------- .../src/model_registry/store/wrapper.py | 21 +++++++++++-------- .../src/model_registry/types/artifacts.py | 8 +++---- .../python/src/model_registry/types/base.py | 8 +++++-- .../src/model_registry/types/contexts.py | 4 ++-- clients/python/tests/store/test_wrapper.py | 4 ++-- .../tests/types/test_artifact_mapping.py | 12 +++++++---- .../tests/types/test_context_mapping.py | 10 +++++++-- 8 files changed, 50 insertions(+), 37 deletions(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index ddebc98d..3ffc45d0 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -8,7 +8,7 @@ from .exceptions import StoreException from .store import ProtoType, MLMDStore from .types import ModelArtifact, ModelVersion, RegisteredModel, ListOptions -from .types.base import Mappable +from .types.base import ProtoBase from .types.options import MLMDListOptions @@ -43,7 +43,7 @@ def __init__( config.ssl_config.custom_ca = custom_ca self._store = MLMDStore(config) - def _map(self, py_obj: Mappable) -> ProtoType: + def _map(self, py_obj: ProtoBase) -> ProtoType: """Map a Python object to a proto object. Helper around the `map` method of the Python object. @@ -54,11 +54,10 @@ def _map(self, py_obj: Mappable) -> ProtoType: Returns: ProtoType: Proto object. """ - proto_obj = py_obj.map() - proto_obj.type_id = self._store.get_type_id( - proto_obj, py_obj.get_proto_type_name() + type_id = self._store.get_type_id( + py_obj.get_proto_type(), py_obj.get_proto_type_name() ) - return proto_obj + return py_obj.map(type_id) def upsert_registered_model(self, registered_model: RegisteredModel) -> str: """Upsert a registered model. @@ -72,8 +71,7 @@ def upsert_registered_model(self, registered_model: RegisteredModel) -> str: Returns: str: ID of the registered model. """ - proto_obj = self._map(registered_model) - id = self._store.put_context(proto_obj) + id = self._store.put_context(self._map(registered_model)) new_py_rm = RegisteredModel.unmap( self._store.get_context(RegisteredModel.get_proto_type_name(), id) ) @@ -164,8 +162,7 @@ def upsert_model_version( rm_id = int(registered_model_id) # this is not ideal but we need this info for the prefix model_version._registered_model_id = rm_id - proto_mv = self._map(model_version) - id = self._store.put_context(proto_mv) + id = self._store.put_context(self._map(model_version)) self._store.put_context_parent(rm_id, id) new_py_mv = ModelVersion.unmap( self._store.get_context(ModelVersion.get_proto_type_name(), id) @@ -284,8 +281,7 @@ def upsert_model_artifact( if "found" not in str(e).lower(): raise model_artifact._model_version_id = model_version_id - proto_ma = self._map(model_artifact) - id = self._store.put_artifact(proto_ma) + id = self._store.put_artifact(self._map(model_artifact)) self._store.put_attribution(mv_id, id) new_py_ma = ModelArtifact.unmap( self._store.get_artifact(ModelArtifact.get_proto_type_name(), id) diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index 8be124d9..8649cacd 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -1,5 +1,5 @@ from collections.abc import Sequence -from typing import Optional +from typing import ClassVar, Optional from ml_metadata.metadata_store import ListOptions, MetadataStore from ml_metadata import errors @@ -25,7 +25,7 @@ class MLMDStore: """MLMD storage backend.""" # cache for MLMD type IDs - _type_ids: dict[str, int] = {} + _type_ids: ClassVar[dict[str, int]] = {} def __init__(self, config: MetadataStoreClientConfig): """Constructor. @@ -35,7 +35,7 @@ def __init__(self, config: MetadataStoreClientConfig): """ self._mlmd_store = MetadataStore(config) - def get_type_id(self, mlmd_pt: ProtoType, type_name: str) -> int: + def get_type_id(self, mlmd_pt: type[ProtoType], type_name: str) -> int: """Get backend ID for a type. Args: @@ -53,10 +53,10 @@ def get_type_id(self, mlmd_pt: ProtoType, type_name: str) -> int: if type_name in self._type_ids: return self._type_ids[type_name] - if isinstance(mlmd_pt, Artifact): + if mlmd_pt is Artifact: mlmd_pt_name = "artifact" get_type = self._mlmd_store.get_artifact_type - elif isinstance(mlmd_pt, Context): + elif mlmd_pt is Context: mlmd_pt_name = "context" get_type = self._mlmd_store.get_context_type else: @@ -132,10 +132,13 @@ def _filter_type( ) -> Sequence[ProtoType]: return [proto for proto in protos if proto.type == type_name] - def get_context(self, ctx_type_name: str, - id: Optional[int] = None, - name: Optional[str] = None, - external_id: Optional[str] = None) -> Context: + def get_context( + self, + ctx_type_name: str, + id: Optional[int] = None, + name: Optional[str] = None, + external_id: Optional[str] = None, + ) -> Context: """Get a context from the store. This gets a context either by ID, name or external ID. diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index dc6ffa14..fe667150 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -56,8 +56,8 @@ def get_proto_type(cls) -> type[Artifact]: return Artifact @override - def map(self) -> Artifact: - mlmd_obj = super().map() + def map(self, type_id: int) -> Artifact: + mlmd_obj = super().map(type_id) mlmd_obj.uri = self.uri mlmd_obj.state = ArtifactState[self.state.name].value return mlmd_obj @@ -108,8 +108,8 @@ def mlmd_name_prefix(self) -> str: return uuid4().hex @override - def map(self) -> Artifact: - mlmd_obj = super().map() + def map(self, type_id: int) -> Artifact: + mlmd_obj = super().map(type_id) props = { "modelFormatName": self.model_format_name, "modelFormatVersion": self.model_format_version, diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index 1da9a474..42c218dc 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -31,9 +31,12 @@ def proto_name(self) -> str: pass @abstractmethod - def map(self) -> ProtoType: + def map(self, type_id: int) -> ProtoType: """Map to a proto object. + Args: + type_id (int): ID of the type. + Returns: ProtoType: Proto object. """ @@ -133,9 +136,10 @@ def _map_props( raise Exception(f"Unsupported type: {type(value)}") @override - def map(self) -> ProtoType: + def map(self, type_id: int) -> ProtoType: mlmd_obj = (self.get_proto_type())() mlmd_obj.name = self.proto_name + mlmd_obj.type_id = type_id if self.id: mlmd_obj.id = int(self.id) if self.external_id: diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 69a79466..f018a204 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -70,8 +70,8 @@ def mlmd_name_prefix(self): return self._registered_model_id @override - def map(self) -> Context: - mlmd_obj = super().map() + def map(self, type_id: int) -> Context: + mlmd_obj = super().map(type_id) # this should match the name of the registered model mlmd_obj.properties["model_name"].string_value = self.model.name mlmd_obj.properties["author"].string_value = self.author diff --git a/clients/python/tests/store/test_wrapper.py b/clients/python/tests/store/test_wrapper.py index 82b52b8f..1a161643 100644 --- a/clients/python/tests/store/test_wrapper.py +++ b/clients/python/tests/store/test_wrapper.py @@ -45,12 +45,12 @@ def context(store_wrapper: MLMDStore) -> Context: def test_get_undefined_artifact_type_id(store_wrapper: MLMDStore): with raises(TypeNotFoundException): - store_wrapper.get_type_id(Artifact(), "undefined") + store_wrapper.get_type_id(Artifact, "undefined") def test_get_undefined_context_type_id(store_wrapper: MLMDStore): with raises(TypeNotFoundException): - store_wrapper.get_type_id(Context(), "undefined") + store_wrapper.get_type_id(Context, "undefined") def test_put_invalid_artifact(store_wrapper: MLMDStore, artifact: Artifact): diff --git a/clients/python/tests/types/test_artifact_mapping.py b/clients/python/tests/types/test_artifact_mapping.py index 3de2ac49..68c1e2c9 100644 --- a/clients/python/tests/types/test_artifact_mapping.py +++ b/clients/python/tests/types/test_artifact_mapping.py @@ -15,6 +15,7 @@ def complete_model() -> Mapped: proto_model = Artifact() proto_model.name = "test_prefix:test_model" + proto_model.type_id = 1 proto_model.external_id = "test_external_id" proto_model.state = Artifact.UNKNOWN proto_model.uri = "test_uri" @@ -44,6 +45,7 @@ def complete_model() -> Mapped: def minimal_model() -> Mapped: proto_model = Artifact() proto_model.name = "test_prefix:test_model" + proto_model.type_id = 1 proto_model.state = Artifact.UNKNOWN proto_model.uri = "test_uri" @@ -54,9 +56,10 @@ def minimal_model() -> Mapped: def test_partial_model_mapping(monkeypatch, minimal_model: Mapped): monkeypatch.setattr(ModelArtifact, "mlmd_name_prefix", "test_prefix") - mapped_model = minimal_model.py.map() + mapped_model = minimal_model.py.map(1) proto_model = minimal_model.proto assert mapped_model.name == proto_model.name + assert mapped_model.type_id == proto_model.type_id assert mapped_model.state == proto_model.state assert mapped_model.uri == proto_model.uri @@ -64,9 +67,10 @@ def test_partial_model_mapping(monkeypatch, minimal_model: Mapped): def test_full_model_mapping(monkeypatch, complete_model: Mapped): monkeypatch.setattr(ModelArtifact, "mlmd_name_prefix", "test_prefix") - mapped_model = complete_model.py.map() + mapped_model = complete_model.py.map(1) proto_model = complete_model.proto assert mapped_model.name == proto_model.name + assert mapped_model.type_id == proto_model.type_id assert mapped_model.state == proto_model.state assert mapped_model.uri == proto_model.uri assert mapped_model.external_id == proto_model.external_id @@ -97,6 +101,6 @@ def test_full_model_unmapping(complete_model: Mapped): def test_model_prefix_generation(minimal_model: Mapped): - name1 = minimal_model.py.map().name - name2 = minimal_model.py.map().name + name1 = minimal_model.py.map(1).name + name2 = minimal_model.py.map(1).name assert name1 != name2 diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index a491e1fd..2175e4b9 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -16,6 +16,7 @@ def full_model_version() -> Mapped: proto_version = Context() proto_version.name = "1:1.0.0" + proto_version.type_id = 2 proto_version.external_id = "test_external_id" proto_version.properties["description"].string_value = "test description" proto_version.properties["model_name"].string_value = "test_model" @@ -27,6 +28,7 @@ def full_model_version() -> Mapped: proto_version.custom_properties["str_key"].string_value = "test_str" py_model = ModelArtifact("test_model", "test_uri") + py_version = ModelVersion( py_model, "1.0.0", @@ -49,26 +51,30 @@ def full_model_version() -> Mapped: def minimal_model_version() -> Mapped: proto_version = Context() proto_version.name = "1:1.0.0" + proto_version.type_id = 2 proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" py_model = ModelArtifact("test_model", "test_uri") + py_version = ModelVersion(py_model, "1.0.0", "test_author") py_version._registered_model_id = 1 return Mapped(proto_version, py_version) def test_partial_model_version_mapping(minimal_model_version: Mapped): - mapped_version = minimal_model_version.py.map() + mapped_version = minimal_model_version.py.map(2) proto_version = minimal_model_version.proto assert mapped_version.name == proto_version.name + assert mapped_version.type_id == proto_version.type_id assert mapped_version.properties == proto_version.properties def test_full_model_version_mapping(full_model_version: Mapped): - mapped_version = full_model_version.py.map() + mapped_version = full_model_version.py.map(2) proto_version = full_model_version.proto assert mapped_version.name == proto_version.name + assert mapped_version.type_id == proto_version.type_id assert mapped_version.external_id == proto_version.external_id assert mapped_version.properties == proto_version.properties assert mapped_version.custom_properties == proto_version.custom_properties From e3ed413e8f63bbeb22bbd81074c667b673ac7c93 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:11 -0300 Subject: [PATCH 158/254] py: fix get_registered_models with empty options Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 3ffc45d0..f7b3f771 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -138,7 +138,7 @@ def get_registered_models( Returns: Sequence[RegisteredModel]: Registered models. """ - mlmd_options = options.as_mlmd_list_options() if options else None + mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() proto_rms = self._store.get_contexts( RegisteredModel.get_proto_type_name(), mlmd_options ) From 864fba641d08480705757335ae221af808147611 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:11 -0300 Subject: [PATCH 159/254] py: share Mapped class among tests Signed-off-by: Isabella Basso do Amaral --- clients/python/tests/__init__.py | 15 +++++++++++++++ clients/python/tests/test_client.py | 11 ++++------- clients/python/tests/types/__init__.py | 8 +------- .../python/tests/types/test_artifact_mapping.py | 2 +- .../python/tests/types/test_context_mapping.py | 5 ++--- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/clients/python/tests/__init__.py b/clients/python/tests/__init__.py index e69de29b..b2b301e1 100644 --- a/clients/python/tests/__init__.py +++ b/clients/python/tests/__init__.py @@ -0,0 +1,15 @@ +"""Tests for model registry.""" + +from dataclasses import dataclass +from typing import Generic, TypeVar + +from model_registry.store import ProtoType +from model_registry.types.base import ProtoBase + +P = TypeVar("P", bound=ProtoBase) + + +@dataclass +class Mapped(Generic[P]): + proto: ProtoType + py: P diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 7f39634a..3186acdd 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -1,14 +1,12 @@ """Tests for user facing model registry APIs.""" -from collections import namedtuple - from attrs import evolve from ml_metadata.proto import ( - ArtifactType, Artifact, + ArtifactType, Attribution, - ContextType, Context, + ContextType, ParentContext, metadata_store_pb2, ) @@ -18,6 +16,8 @@ from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel from pytest import fixture, raises +from . import Mapped + @fixture def model_registry(store_wrapper: MLMDStore) -> ModelRegistry: @@ -26,9 +26,6 @@ def model_registry(store_wrapper: MLMDStore) -> ModelRegistry: return mr -Mapped = namedtuple("Mapped", ["proto", "py"]) - - @fixture def model(store_wrapper: MLMDStore) -> Mapped: art_type = ArtifactType() diff --git a/clients/python/tests/types/__init__.py b/clients/python/tests/types/__init__.py index d42ec313..04c524de 100644 --- a/clients/python/tests/types/__init__.py +++ b/clients/python/tests/types/__init__.py @@ -1,7 +1 @@ -"""Tests for model registry types -""" - -from collections import namedtuple - - -Mapped = namedtuple("Mapped", ["proto", "py"]) +"""Tests for model registry types.""" diff --git a/clients/python/tests/types/test_artifact_mapping.py b/clients/python/tests/types/test_artifact_mapping.py index 68c1e2c9..5910f048 100644 --- a/clients/python/tests/types/test_artifact_mapping.py +++ b/clients/python/tests/types/test_artifact_mapping.py @@ -8,7 +8,7 @@ from model_registry.types import ModelArtifact from pytest import fixture -from . import Mapped +from .. import Mapped @fixture diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index 2175e4b9..0e16a6cd 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -4,12 +4,11 @@ * should we parametrize the tests? """ -from pytest import fixture from ml_metadata.proto import Context - from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel +from pytest import fixture -from . import Mapped +from .. import Mapped @fixture From 7f967e70b5455bae310dcd5b171ee615b67ead96 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:11 -0300 Subject: [PATCH 160/254] py: add ruff rules Signed-off-by: Isabella Basso do Amaral --- clients/python/pyproject.toml | 35 +++- clients/python/src/model_registry/client.py | 50 +++--- .../python/src/model_registry/exceptions.py | 3 +- .../src/model_registry/store/__init__.py | 6 +- .../python/src/model_registry/store/base.py | 3 +- .../src/model_registry/store/wrapper.py | 155 ++++++++++++------ .../src/model_registry/types/__init__.py | 5 +- .../src/model_registry/types/artifacts.py | 20 +-- .../python/src/model_registry/types/base.py | 26 +-- .../src/model_registry/types/contexts.py | 5 +- .../src/model_registry/types/options.py | 9 +- clients/python/tests/conftest.py | 4 +- clients/python/tests/store/test_wrapper.py | 26 +-- clients/python/tests/test_client.py | 16 +- .../tests/types/test_artifact_mapping.py | 10 +- .../tests/types/test_context_mapping.py | 12 +- 16 files changed, 230 insertions(+), 155 deletions(-) diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index bfa7223d..515eaff5 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -40,7 +40,40 @@ line-length = 119 [tool.ruff] target-version = "py39" -ignore = ["E501"] +select = [ + "F", # pyflakes + # pycodestyle + "W", # warnings + "E", # errors + + "C90", # mccabe + "B", # bugbear + "S", # flake8-bandit + + "C4", # flake8-comprehensions + "D", # pydocstyle + "EM", # flake8-errmsg + "I", # isort + "PT", # pytest + "Q", # flake8-quotes + "RET", # flake8-return + "SIM", # flake8-simplify + "UP", # pyupgrade +] +respect-gitignore = true +ignore = [ + "D105", # missing docstring in magic method + "E501", # line too long + "S101", # use of assert detected +] + +[tool.ruff.lint.pydocstyle] +convention = "google" + +[tool.ruff.per-file-ignores] +"tests/**/*.py" = [ + "D", # missing docstring in public module +] [tool.ruff.mccabe] max-complexity = 8 diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index f7b3f771..f5d53ae1 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -1,13 +1,13 @@ -"""Client for the model registry. -""" +"""Client for the model registry.""" +from __future__ import annotations + from collections.abc import Sequence -from typing import Optional from ml_metadata.proto import MetadataStoreClientConfig from .exceptions import StoreException -from .store import ProtoType, MLMDStore -from .types import ModelArtifact, ModelVersion, RegisteredModel, ListOptions +from .store import MLMDStore, ProtoType +from .types import ListOptions, ModelArtifact, ModelVersion, RegisteredModel from .types.base import ProtoBase from .types.options import MLMDListOptions @@ -19,9 +19,9 @@ def __init__( self, server_address: str, port: int, - client_key: Optional[str] = None, - server_cert: Optional[str] = None, - custom_ca: Optional[str] = None, + client_key: str | None = None, + server_cert: str | None = None, + custom_ca: str | None = None, ): """Constructor. @@ -101,7 +101,7 @@ def get_registered_model_by_id(self, id: str) -> RegisteredModel: return py_rm def get_registered_model_by_params( - self, name: Optional[str] = None, external_id: Optional[str] = None + self, name: str | None = None, external_id: str | None = None ) -> RegisteredModel: """Fetch a registered model by its name or external ID. @@ -113,7 +113,8 @@ def get_registered_model_by_params( RegisteredModel: Registered model. """ if name is None and external_id is None: - raise StoreException("Either name or external_id must be provided") + msg = "Either name or external_id must be provided" + raise StoreException(msg) py_rm = RegisteredModel.unmap( self._store.get_context( RegisteredModel.get_proto_type_name(), @@ -128,7 +129,7 @@ def get_registered_model_by_params( return py_rm def get_registered_models( - self, options: Optional[ListOptions] = None + self, options: ListOptions | None = None ) -> Sequence[RegisteredModel]: """Fetch registered models. @@ -195,7 +196,7 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: return py_mv def get_model_versions( - self, registered_model_id: str, options: Optional[ListOptions] = None + self, registered_model_id: str, options: ListOptions | None = None ) -> Sequence[ModelVersion]: """Fetch model versions by registered model ID. @@ -221,9 +222,9 @@ def get_model_versions( def get_model_version_by_params( self, - registered_model_id: Optional[str] = None, - version: Optional[str] = None, - external_id: Optional[str] = None, + registered_model_id: str | None = None, + version: str | None = None, + external_id: str | None = None, ) -> ModelVersion: """Fetch a model version by associated parameters. @@ -242,9 +243,10 @@ def get_model_version_by_params( ModelVersion.get_proto_type_name(), external_id=external_id ) elif registered_model_id is None or version is None: - raise StoreException( + msg = ( "Either registered_model_id and version or external_id must be provided" ) + raise StoreException(msg) else: proto_mv = self._store.get_context( ModelVersion.get_proto_type_name(), @@ -274,9 +276,8 @@ def upsert_model_artifact( self._store.get_attributed_artifact( ModelArtifact.get_proto_type_name(), mv_id ) - raise StoreException( - f"Model version with ID {mv_id} already has a model artifact" - ) + msg = f"Model version with ID {mv_id} already has a model artifact" + raise StoreException(msg) except StoreException as e: if "found" not in str(e).lower(): raise @@ -309,7 +310,7 @@ def get_model_artifact_by_id(self, id: str) -> ModelArtifact: return ModelArtifact.unmap(proto_ma) def get_model_artifact_by_params( - self, model_version_id: Optional[str] = None, external_id: Optional[str] = None + self, model_version_id: str | None = None, external_id: str | None = None ) -> ModelArtifact: """Fetch a model artifact either by external ID or by the ID of its associated model version. @@ -325,9 +326,8 @@ def get_model_artifact_by_params( ModelArtifact.get_proto_type_name(), external_id=external_id ) elif not model_version_id: - raise StoreException( - "Either model_version_id or external_id must be provided" - ) + msg = "Either model_version_id or external_id must be provided" + raise StoreException(msg) else: proto_ma = self._store.get_attributed_artifact( ModelArtifact.get_proto_type_name(), int(model_version_id) @@ -336,8 +336,8 @@ def get_model_artifact_by_params( def get_model_artifacts( self, - model_version_id: Optional[str] = None, - options: Optional[ListOptions] = None, + model_version_id: str | None = None, + options: ListOptions | None = None, ) -> Sequence[ModelArtifact]: """Fetches model artifacts. diff --git a/clients/python/src/model_registry/exceptions.py b/clients/python/src/model_registry/exceptions.py index a5b6c8e6..bac601d2 100644 --- a/clients/python/src/model_registry/exceptions.py +++ b/clients/python/src/model_registry/exceptions.py @@ -1,5 +1,4 @@ -"""Exceptions for the model registry. -""" +"""Exceptions for the model registry.""" class StoreException(Exception): diff --git a/clients/python/src/model_registry/store/__init__.py b/clients/python/src/model_registry/store/__init__.py index 147af466..d35c2750 100644 --- a/clients/python/src/model_registry/store/__init__.py +++ b/clients/python/src/model_registry/store/__init__.py @@ -1,10 +1,10 @@ -"""Model registry storage backends. -""" +"""Model registry storage backends.""" from .base import ProtoType, ScalarType from .wrapper import MLMDStore __all__ = [ - "ProtoType", "ScalarType", + "ProtoType", + "ScalarType", "MLMDStore", ] diff --git a/clients/python/src/model_registry/store/base.py b/clients/python/src/model_registry/store/base.py index 8b5c9b8c..ca381f8e 100644 --- a/clients/python/src/model_registry/store/base.py +++ b/clients/python/src/model_registry/store/base.py @@ -1,8 +1,9 @@ +"""Base classes and types for MLMD store.""" + from typing import Union from ml_metadata.proto import Artifact, Context - ProtoType = Union[Artifact, Context] """Union of all proto types. """ ScalarType = Union[str, int, float, bool] diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index 8649cacd..71ff8688 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -1,8 +1,12 @@ +"""MLMD storage backend wrapper.""" + +from __future__ import annotations + from collections.abc import Sequence -from typing import ClassVar, Optional +from typing import ClassVar -from ml_metadata.metadata_store import ListOptions, MetadataStore from ml_metadata import errors +from ml_metadata.metadata_store import ListOptions, MetadataStore from ml_metadata.proto import ( Artifact, Attribution, @@ -11,7 +15,6 @@ ParentContext, ) -from .base import ProtoType from model_registry.exceptions import ( DuplicateException, ServerException, @@ -20,6 +23,8 @@ UnsupportedTypeException, ) +from .base import ProtoType + class MLMDStore: """MLMD storage backend.""" @@ -60,18 +65,17 @@ def get_type_id(self, mlmd_pt: type[ProtoType], type_name: str) -> int: mlmd_pt_name = "context" get_type = self._mlmd_store.get_context_type else: - raise UnsupportedTypeException(f"Unsupported type: {mlmd_pt}") + msg = f"Unsupported type: {mlmd_pt}" + raise UnsupportedTypeException(msg) try: _type = get_type(type_name) except errors.NotFoundError as e: - raise TypeNotFoundException( - f"{mlmd_pt_name} type {type_name} does not exist" - ) from e + msg = f"{mlmd_pt_name} type {type_name} does not exist" + raise TypeNotFoundException(msg) from e except errors.InternalError as e: - raise ServerException( - f"Couldn't get {mlmd_pt_name} type {type_name} from MLMD store" - ) from e + msg = f"Couldn't get {mlmd_pt_name} type {type_name} from MLMD store" + raise ServerException(msg) from e self._type_ids[type_name] = _type.id @@ -94,13 +98,14 @@ def put_artifact(self, artifact: Artifact) -> int: try: return self._mlmd_store.put_artifacts([artifact])[0] except errors.AlreadyExistsError as e: - raise DuplicateException(f"Artifact {artifact.name} already exists") from e + msg = f"Artifact {artifact.name} already exists" + raise DuplicateException(msg) from e except errors.InvalidArgumentError as e: - raise StoreException("Artifact has invalid properties") from e + msg = "Artifact has invalid properties" + raise StoreException(msg) from e except errors.NotFoundError as e: - raise TypeNotFoundException( - f"Artifact type {artifact.type} does not exist" - ) from e + msg = f"Artifact type {artifact.type} does not exist" + raise TypeNotFoundException(msg) from e def put_context(self, context: Context) -> int: """Put a context in the store. @@ -119,13 +124,14 @@ def put_context(self, context: Context) -> int: try: return self._mlmd_store.put_contexts([context])[0] except errors.AlreadyExistsError as e: - raise DuplicateException(f"Context {context.name} already exists") from e + msg = f"Context {context.name} already exists" + raise DuplicateException(msg) from e except errors.InvalidArgumentError as e: - raise StoreException("Context has invalid properties") from e + msg = "Context has invalid properties" + raise StoreException(msg) from e except errors.NotFoundError as e: - raise TypeNotFoundException( - f"Context type {context.type} does not exist" - ) from e + msg = f"Context type {context.type} does not exist" + raise TypeNotFoundException(msg) from e def _filter_type( self, type_name: str, protos: Sequence[ProtoType] @@ -135,9 +141,9 @@ def _filter_type( def get_context( self, ctx_type_name: str, - id: Optional[int] = None, - name: Optional[str] = None, - external_id: Optional[str] = None, + id: int | None = None, + name: str | None = None, + external_id: str | None = None, ) -> Context: """Get a context from the store. @@ -164,32 +170,46 @@ def get_context( elif external_id is not None: contexts = self._mlmd_store.get_contexts_by_external_ids([external_id]) else: - raise StoreException("Either id, name or external_id must be provided") + msg = "Either id, name or external_id must be provided" + raise StoreException(msg) contexts = self._filter_type(ctx_type_name, contexts) if contexts: return contexts[0] - raise StoreException(f"Context with ID {id} does not exist") + msg = f"Context with ID {id} does not exist" + raise StoreException(msg) def get_contexts( self, ctx_type_name: str, options: ListOptions ) -> Sequence[Context]: + """Get contexts from the store. + + Args: + ctx_type_name (str): Name of the context type. + options (ListOptions): List options. + + Returns: + Sequence[Context]: Contexts. + """ # TODO: should we make options optional? # if options is not None: try: contexts = self._mlmd_store.get_contexts(options) except errors.InvalidArgumentError as e: - raise StoreException(f"Invalid arguments for get_contexts: {e}") from e + msg = f"Invalid arguments for get_contexts: {e}" + raise StoreException(msg) from e except errors.InternalError as e: - raise ServerException("Couldn't get contexts from MLMD store") from e + msg = "Couldn't get contexts from MLMD store" + raise ServerException(msg) from e contexts = self._filter_type(ctx_type_name, contexts) # else: # contexts = self._mlmd_store.get_contexts_by_type(ctx_type_name) if not contexts: - raise StoreException(f"Context type {ctx_type_name} does not exist") + msg = f"Context type {ctx_type_name} does not exist" + raise StoreException(msg) return contexts @@ -209,13 +229,11 @@ def put_context_parent(self, parent_id: int, child_id: int): [ParentContext(parent_id=parent_id, child_id=child_id)] ) except errors.AlreadyExistsError as e: - raise StoreException( - f"Parent context {parent_id} already exists for context {child_id}" - ) from e + msg = f"Parent context {parent_id} already exists for context {child_id}" + raise StoreException(msg) from e except errors.InternalError as e: - raise ServerException( - f"Couldn't put parent context {parent_id} for context {child_id}" - ) from e + msg = f"Couldn't put parent context {parent_id} for context {child_id}" + raise ServerException(msg) from e def put_attribution(self, context_id: int, artifact_id: int): """Put an attribution relationship between a context and an artifact. @@ -232,28 +250,32 @@ def put_attribution(self, context_id: int, artifact_id: int): self._mlmd_store.put_attributions_and_associations([attribution], []) except errors.InvalidArgumentError as e: if "artifact" in str(e).lower(): - raise StoreException( - f"Artifact with ID {artifact_id} does not exist" - ) from e - elif "context" in str(e).lower(): - raise StoreException( - f"Context with ID {context_id} does not exist" - ) from e - else: - raise StoreException(f"Invalid argument: {e}") from e + msg = f"Artifact with ID {artifact_id} does not exist" + raise StoreException(msg) from e + + if "context" in str(e).lower(): + msg = f"Context with ID {context_id} does not exist" + raise StoreException(msg) from e + + msg = f"Invalid argument: {e}" + raise StoreException(msg) from e def get_artifact( self, art_type_name: str, - id: Optional[int] = None, - name: Optional[str] = None, - external_id: Optional[str] = None, + id: int | None = None, + name: str | None = None, + external_id: str | None = None, ) -> Artifact: """Get an artifact from the store. + Gets an artifact either by ID, name or external ID. + Args: art_type_name (str): Name of the artifact type. - id (int): ID of the artifact. + id (int, optional): ID of the artifact. + name (str, optional): Name of the artifact. + external_id (str, optional): External ID of the artifact. Returns: Artifact: Artifact. @@ -269,36 +291,61 @@ def get_artifact( elif external_id is not None: artifacts = self._mlmd_store.get_artifacts_by_external_ids([external_id]) else: - raise StoreException("Either id, name or external_id must be provided") + msg = "Either id, name or external_id must be provided" + raise StoreException(msg) artifacts = self._filter_type(art_type_name, artifacts) if artifacts: return artifacts[0] - raise StoreException(f"Artifact with ID {id} does not exist") + msg = f"Artifact with ID {id} does not exist" + raise StoreException(msg) def get_attributed_artifact(self, art_type_name: str, ctx_id: int) -> Artifact: + """Get an artifact from the store by its attributed context. + + Args: + art_type_name (str): Name of the artifact type. + ctx_id (int): ID of the context. + + Returns: + Artifact: Artifact. + """ try: artifacts = self._mlmd_store.get_artifacts_by_context(ctx_id) except errors.InternalError as e: - raise ServerException(f"Couldn't get artifacts by context {ctx_id}") from e + msg = f"Couldn't get artifacts by context {ctx_id}" + raise ServerException(msg) from e artifacts = self._filter_type(art_type_name, artifacts) if artifacts: return artifacts[0] - raise StoreException("No artifacts found") + msg = "No artifacts found" + raise StoreException(msg) def get_artifacts( self, art_type_name: str, options: ListOptions ) -> Sequence[Artifact]: + """Get artifacts from the store. + + Args: + art_type_name (str): Name of the artifact type. + options (ListOptions): List options. + + Returns: + Sequence[Artifact]: Artifacts. + """ try: artifacts = self._mlmd_store.get_artifacts(options) except errors.InvalidArgumentError as e: - raise StoreException(f"Invalid arguments for get_artifacts: {e}") from e + msg = f"Invalid arguments for get_artifacts: {e}" + raise StoreException(msg) from e except errors.InternalError as e: - raise ServerException("Couldn't get artifacts from MLMD store") from e + msg = "Couldn't get artifacts from MLMD store" + raise ServerException(msg) from e artifacts = self._filter_type(art_type_name, artifacts) if not artifacts: - raise StoreException(f"Artifact type {art_type_name} does not exist") + msg = f"Artifact type {art_type_name} does not exist" + raise StoreException(msg) return artifacts diff --git a/clients/python/src/model_registry/types/__init__.py b/clients/python/src/model_registry/types/__init__.py index 3009db27..df61a02c 100644 --- a/clients/python/src/model_registry/types/__init__.py +++ b/clients/python/src/model_registry/types/__init__.py @@ -1,7 +1,6 @@ -"""Model registry types. -""" +"""Model registry types.""" -from .artifacts import ModelArtifact, ArtifactState +from .artifacts import ArtifactState, ModelArtifact from .contexts import ModelVersion, RegisteredModel from .options import ListOptions, OrderByField diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index fe667150..82b9cce4 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -6,14 +6,13 @@ Those types are used to map between proto types based on artifacts and Python objects. -TODO: +Todo: * Move part of the description to API Reference docs (#120). """ from __future__ import annotations from enum import Enum, unique -from typing import Optional from uuid import uuid4 from attrs import define, field @@ -91,21 +90,18 @@ class ModelArtifact(BaseArtifact, Prefixable): """ # TODO: this could be an enum of valid formats - model_format_name: Optional[str] = field(kw_only=True, default=None) - model_format_version: Optional[str] = field(kw_only=True, default=None) - storage_key: Optional[str] = field(kw_only=True, default=None) - storage_path: Optional[str] = field(kw_only=True, default=None) - service_account_name: Optional[str] = field(kw_only=True, default=None) + model_format_name: str | None = field(kw_only=True, default=None) + model_format_version: str | None = field(kw_only=True, default=None) + storage_key: str | None = field(kw_only=True, default=None) + storage_path: str | None = field(kw_only=True, default=None) + service_account_name: str | None = field(kw_only=True, default=None) - _model_version_id: Optional[str] = field(init=False, default=None) + _model_version_id: str | None = field(init=False, default=None) @property @override def mlmd_name_prefix(self) -> str: - if self._model_version_id: - return self._model_version_id - else: - return uuid4().hex + return self._model_version_id if self._model_version_id else uuid4().hex @override def map(self, type_id: int) -> Artifact: diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index 42c218dc..22e3f9aa 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -4,7 +4,7 @@ from abc import ABC, abstractmethod from collections.abc import Mapping -from typing import Any, Optional, TypeVar +from typing import Any, TypeVar from attrs import define, field from typing_extensions import override @@ -17,7 +17,7 @@ class Mappable(ABC): @classmethod def get_proto_type_name(cls) -> str: - """Name of the proto type + """Name of the proto type. Returns: str: Name of the class prefixed with `odh.` @@ -48,7 +48,7 @@ def unmap(cls, mlmd_obj: ProtoType) -> Mappable: """Map from a proto object. Args: - ProtoType: Proto object. + mlmd_obj (ProtoType): Proto object. Returns: Mappable: Python object. @@ -72,7 +72,7 @@ def mlmd_name_prefix(self) -> str: @define(slots=False, init=False) class ProtoBase(Mappable, ABC): - """Abstract base type for protos + """Abstract base type for protos. This is a type defining common functionality for all types representing Model Registry protos, such as Artifacts, Contexts, and Executions. @@ -87,11 +87,11 @@ class ProtoBase(Mappable, ABC): """ name: str = field(init=False) - id: Optional[str] = field(init=False, default=None) - description: Optional[str] = field(kw_only=True, default=None) - external_id: Optional[str] = field(kw_only=True, default=None) - create_time_since_epoch: Optional[int] = field(init=False, default=None) - last_update_time_since_epoch: Optional[int] = field(init=False, default=None) + id: str | None = field(init=False, default=None) + description: str | None = field(kw_only=True, default=None) + external_id: str | None = field(kw_only=True, default=None) + create_time_since_epoch: int | None = field(init=False, default=None) + last_update_time_since_epoch: int | None = field(init=False, default=None) @property @override @@ -112,7 +112,7 @@ def get_proto_type(cls) -> type[ProtoType]: @staticmethod def _map_props( - py_props: Mapping[str, Optional[ScalarType]], mlmd_props: dict[str, Any] + py_props: Mapping[str, ScalarType | None], mlmd_props: dict[str, Any] ): """Map properties from Python to proto. @@ -133,7 +133,8 @@ def _map_props( elif isinstance(value, str): mlmd_props[key].string_value = value else: - raise Exception(f"Unsupported type: {type(value)}") + msg = f"Unsupported type: {type(value)}" + raise Exception(msg) @override def map(self, type_id: int) -> ProtoType: @@ -170,7 +171,8 @@ def _unmap_props(mlmd_props: dict[str, Any]) -> dict[str, ScalarType]: elif value.HasField("string_value"): py_props[key] = value.string_value else: - raise Exception(f"Unsupported type: {type(value)}") + msg = f"Unsupported type: {type(value)}" + raise Exception(msg) return py_props diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index f018a204..23d417dc 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -5,14 +5,13 @@ Those types are used to map between proto types based on contexts and Python objects. -TODO: +Todo: * Move part of the description to API Reference docs (#120). """ from __future__ import annotations from abc import ABC -from typing import Optional from attrs import define, field from ml_metadata.proto import Context @@ -56,7 +55,7 @@ class ModelVersion(BaseContext, Prefixable): tags: list[str] = field(init=False, factory=list) metadata: dict[str, ScalarType] = field(init=False, factory=dict) - _registered_model_id: Optional[int] = field(init=False, default=None) + _registered_model_id: int | None = field(init=False, default=None) def __attrs_post_init__(self) -> None: self.name = self.version diff --git a/clients/python/src/model_registry/types/options.py b/clients/python/src/model_registry/types/options.py index 8b1a17c9..44b79824 100644 --- a/clients/python/src/model_registry/types/options.py +++ b/clients/python/src/model_registry/types/options.py @@ -3,10 +3,11 @@ Provides a thin wrappers around the options classes defined in the MLMD Py lib. """ -from attrs import define, field +from __future__ import annotations + from enum import Enum -from typing import Optional +from attrs import define, field from ml_metadata.metadata_store import ListOptions as MLMDListOptions from ml_metadata.metadata_store import OrderByField as MLMDOrderByField @@ -29,8 +30,8 @@ class ListOptions: is_asc (bool): Whether to order in ascending order. Defaults to True. """ - limit: Optional[int] = field(default=None) - order_by: Optional[OrderByField] = field(default=None) + limit: int | None = field(default=None) + order_by: OrderByField | None = field(default=None) is_asc: bool = field(default=True) def as_mlmd_list_options(self) -> MLMDListOptions: diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py index 81490b29..c92ac722 100644 --- a/clients/python/tests/conftest.py +++ b/clients/python/tests/conftest.py @@ -1,9 +1,9 @@ +import pytest from ml_metadata.proto import ConnectionConfig from model_registry.store.wrapper import MLMDStore -from pytest import fixture -@fixture +@pytest.fixture() def store_wrapper() -> MLMDStore: config = ConnectionConfig() config.fake_database.SetInParent() diff --git a/clients/python/tests/store/test_wrapper.py b/clients/python/tests/store/test_wrapper.py index 1a161643..d5fcd5f7 100644 --- a/clients/python/tests/store/test_wrapper.py +++ b/clients/python/tests/store/test_wrapper.py @@ -4,6 +4,7 @@ are already covered by the Registry client. """ +import pytest from ml_metadata.proto import ( Artifact, ArtifactType, @@ -16,10 +17,9 @@ TypeNotFoundException, ) from model_registry.store import MLMDStore -from pytest import fixture, raises -@fixture +@pytest.fixture() def artifact(store_wrapper: MLMDStore) -> Artifact: art_type = ArtifactType() art_type.name = "test_artifact" @@ -31,7 +31,7 @@ def artifact(store_wrapper: MLMDStore) -> Artifact: return art -@fixture +@pytest.fixture() def context(store_wrapper: MLMDStore) -> Context: ctx_type = ContextType() ctx_type.name = "test_context" @@ -44,39 +44,39 @@ def context(store_wrapper: MLMDStore) -> Context: def test_get_undefined_artifact_type_id(store_wrapper: MLMDStore): - with raises(TypeNotFoundException): + with pytest.raises(TypeNotFoundException): store_wrapper.get_type_id(Artifact, "undefined") def test_get_undefined_context_type_id(store_wrapper: MLMDStore): - with raises(TypeNotFoundException): + with pytest.raises(TypeNotFoundException): store_wrapper.get_type_id(Context, "undefined") def test_put_invalid_artifact(store_wrapper: MLMDStore, artifact: Artifact): artifact.properties["null"].int_value = 0 - with raises(StoreException): + with pytest.raises(StoreException): store_wrapper.put_artifact(artifact) def test_put_duplicate_artifact(store_wrapper: MLMDStore, artifact: Artifact): store_wrapper._mlmd_store.put_artifacts([artifact]) - with raises(DuplicateException): + with pytest.raises(DuplicateException): store_wrapper.put_artifact(artifact) def test_put_invalid_context(store_wrapper: MLMDStore, context: Context): context.properties["null"].int_value = 0 - with raises(StoreException): + with pytest.raises(StoreException): store_wrapper.put_context(context) def test_put_duplicate_context(store_wrapper: MLMDStore, context: Context): store_wrapper._mlmd_store.put_contexts([context]) - with raises(DuplicateException): + with pytest.raises(DuplicateException): store_wrapper.put_context(context) @@ -85,7 +85,7 @@ def test_put_attribution_with_invalid_context( ): art_id = store_wrapper._mlmd_store.put_artifacts([artifact])[0] - with raises(StoreException) as store_error: + with pytest.raises(StoreException) as store_error: store_wrapper.put_attribution(0, art_id) assert "context" in str(store_error.value).lower() @@ -96,17 +96,17 @@ def test_put_attribution_with_invalid_artifact( ): ctx_id = store_wrapper._mlmd_store.put_contexts([context])[0] - with raises(StoreException) as store_error: + with pytest.raises(StoreException) as store_error: store_wrapper.put_attribution(ctx_id, 0) assert "artifact" in str(store_error.value).lower() def test_get_undefined_artifact_by_id(store_wrapper: MLMDStore): - with raises(StoreException): + with pytest.raises(StoreException): store_wrapper.get_artifact("dup", 0) def test_get_undefined_context_by_id(store_wrapper: MLMDStore): - with raises(StoreException): + with pytest.raises(StoreException): store_wrapper.get_context("dup", 0) diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 3186acdd..e55721b3 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -1,5 +1,6 @@ """Tests for user facing model registry APIs.""" +import pytest from attrs import evolve from ml_metadata.proto import ( Artifact, @@ -14,19 +15,18 @@ from model_registry.exceptions import StoreException from model_registry.store import MLMDStore from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel -from pytest import fixture, raises from . import Mapped -@fixture +@pytest.fixture() def model_registry(store_wrapper: MLMDStore) -> ModelRegistry: mr = object.__new__(ModelRegistry) mr._store = store_wrapper return mr -@fixture +@pytest.fixture() def model(store_wrapper: MLMDStore) -> Mapped: art_type = ArtifactType() art_type.name = ModelArtifact.get_proto_type_name() @@ -50,7 +50,7 @@ def model(store_wrapper: MLMDStore) -> Mapped: return Mapped(art, ModelArtifact("model", "uri")) -@fixture +@pytest.fixture() def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: ctx_type = ContextType() ctx_type.name = ModelVersion.get_proto_type_name() @@ -73,7 +73,7 @@ def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: return Mapped(ctx, ModelVersion(model.py, "version", "author")) -@fixture +@pytest.fixture() def registered_model(store_wrapper: MLMDStore, model: Mapped) -> Mapped: ctx_type = ContextType() ctx_type.name = RegisteredModel.get_proto_type_name() @@ -373,7 +373,7 @@ def test_upsert_duplicate_model_artifact_with_same_version( ma1 = evolve(model.py) model_registry.upsert_model_artifact(ma1, mv_id) ma2 = evolve(model.py) - with raises(StoreException): + with pytest.raises(StoreException): model_registry.upsert_model_artifact(ma2, mv_id) @@ -427,9 +427,7 @@ def test_get_model_artifact_by_external_id( assert mlmd_ma.name != model.proto.name -def test_get_all_model_artifacts( - model_registry: ModelRegistry, model: Mapped, model_version: Mapped -): +def test_get_all_model_artifacts(model_registry: ModelRegistry, model: Mapped): model.proto.name = "test_prefix:model1" ma1_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] model.proto.name = "test_prefix:model2" diff --git a/clients/python/tests/types/test_artifact_mapping.py b/clients/python/tests/types/test_artifact_mapping.py index 5910f048..635a4c0e 100644 --- a/clients/python/tests/types/test_artifact_mapping.py +++ b/clients/python/tests/types/test_artifact_mapping.py @@ -1,17 +1,17 @@ -"""Tests for artifact type mapping +"""Tests for artifact type mapping. -TODO: +Todo: * should we parametrize the tests? """ +import pytest from ml_metadata.proto import Artifact from model_registry.types import ModelArtifact -from pytest import fixture from .. import Mapped -@fixture +@pytest.fixture() def complete_model() -> Mapped: proto_model = Artifact() proto_model.name = "test_prefix:test_model" @@ -41,7 +41,7 @@ def complete_model() -> Mapped: return Mapped(proto_model, py_model) -@fixture +@pytest.fixture() def minimal_model() -> Mapped: proto_model = Artifact() proto_model.name = "test_prefix:test_model" diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index 0e16a6cd..98d8db22 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -1,17 +1,17 @@ -"""Tests for context type mapping +"""Tests for context type mapping. -TODO: +Todo: * should we parametrize the tests? """ +import pytest from ml_metadata.proto import Context -from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel -from pytest import fixture +from model_registry.types import ModelArtifact, ModelVersion from .. import Mapped -@fixture +@pytest.fixture() def full_model_version() -> Mapped: proto_version = Context() proto_version.name = "1:1.0.0" @@ -46,7 +46,7 @@ def full_model_version() -> Mapped: return Mapped(proto_version, py_version) -@fixture +@pytest.fixture() def minimal_model_version() -> Mapped: proto_version = Context() proto_version.name = "1:1.0.0" From 4bc9b8d550d248b9b5caa2f443838bb7631c7869 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:13 -0300 Subject: [PATCH 161/254] py: fix artifact storage docstrings Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/types/artifacts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index 82b9cce4..fce6b4f5 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -84,9 +84,9 @@ class ModelArtifact(BaseArtifact, Prefixable): external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. model_format_name (str, optional): Name of the model format. model_format_version (str, optional): Version of the model format. - storage_key (str, optional): Storage key of the model. + storage_key (str, optional): Storage secret name. storage_path (str, optional): Storage path of the model. - service_account_name (str, optional): Service account name of the model. + service_account_name (str, optional): Name of the service account with storage secret. """ # TODO: this could be an enum of valid formats From b4eebd6c073b1b047c94de198157cae2549d4bfd Mon Sep 17 00:00:00 2001 From: Isabella Basso Date: Thu, 23 Nov 2023 15:24:43 -0300 Subject: [PATCH 162/254] py: remove type annotations on docstrings There's no need to duplicate PEP484 type annotations as per Google's docstring style [1]. [1]: https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html --- clients/python/src/model_registry/client.py | 78 +++++++++---------- .../src/model_registry/store/wrapper.py | 62 +++++++-------- .../src/model_registry/types/artifacts.py | 24 +++--- .../python/src/model_registry/types/base.py | 30 +++---- .../src/model_registry/types/contexts.py | 24 +++--- .../src/model_registry/types/options.py | 8 +- 6 files changed, 113 insertions(+), 113 deletions(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index f5d53ae1..868b4224 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -26,11 +26,11 @@ def __init__( """Constructor. Args: - server_address (str): Server address. - port (int): Server port. - client_key (str, optional): The PEM-encoded private key as a byte string. - server_cert (str, optional): The PEM-encoded certificate as a byte string. - custom_ca (str, optional): The PEM-encoded root certificates as a byte string. + server_address: Server address. + port: Server port. + client_key: The PEM-encoded private key as a byte string. + server_cert: The PEM-encoded certificate as a byte string. + custom_ca: The PEM-encoded root certificates as a byte string. """ config = MetadataStoreClientConfig() config.host = server_address @@ -49,10 +49,10 @@ def _map(self, py_obj: ProtoBase) -> ProtoType: Helper around the `map` method of the Python object. Args: - py_obj (Mappable): Python object. + py_obj: Python object. Returns: - ProtoType: Proto object. + Proto object. """ type_id = self._store.get_type_id( py_obj.get_proto_type(), py_obj.get_proto_type_name() @@ -66,10 +66,10 @@ def upsert_registered_model(self, registered_model: RegisteredModel) -> str: This updates the registered_model instance passed in with new data from the servers. Args: - registered_model (RegisteredModel): Registered model. + registered_model: Registered model. Returns: - str: ID of the registered model. + ID of the registered model. """ id = self._store.put_context(self._map(registered_model)) new_py_rm = RegisteredModel.unmap( @@ -87,10 +87,10 @@ def get_registered_model_by_id(self, id: str) -> RegisteredModel: """Fetch a registered model by its ID. Args: - id (str): Registered model ID. + id: Registered model ID. Returns: - RegisteredModel: Registered model. + Registered model. """ py_rm = RegisteredModel.unmap( self._store.get_context(RegisteredModel.get_proto_type_name(), id=int(id)) @@ -106,11 +106,11 @@ def get_registered_model_by_params( """Fetch a registered model by its name or external ID. Args: - name (str, optional): Registered model name. - external_id (str, optional): Registered model external ID. + name: Registered model name. + external_id: Registered model external ID. Returns: - RegisteredModel: Registered model. + Registered model. """ if name is None and external_id is None: msg = "Either name or external_id must be provided" @@ -134,10 +134,10 @@ def get_registered_models( """Fetch registered models. Args: - options (ListOptions, optional): Options for listing registered models. + options: Options for listing registered models. Returns: - Sequence[RegisteredModel]: Registered models. + Registered models. """ mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() proto_rms = self._store.get_contexts( @@ -154,11 +154,11 @@ def upsert_model_version( This updates the model_version instance passed in with new data from the servers. Args: - model_version (ModelVersion): Model version to upsert. - registered_model_id (str): ID of the registered model this version will be associated to. + model_version: Model version to upsert. + registered_model_id: ID of the registered model this version will be associated to. Returns: - str: ID of the model version. + ID of the model version. """ rm_id = int(registered_model_id) # this is not ideal but we need this info for the prefix @@ -180,10 +180,10 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: """Fetch a model version by its ID. Args: - model_version_id (str): Model version ID. + model_version_id: Model version ID. Returns: - ModelVersion: Model version. + Model version. """ py_mv = ModelVersion.unmap( self._store.get_context( @@ -201,11 +201,11 @@ def get_model_versions( """Fetch model versions by registered model ID. Args: - registered_model_id (str): Registered model ID. - options (ListOptions, optional): Options for listing model versions. + registered_model_id: Registered model ID. + options: Options for listing model versions. Returns: - Sequence[ModelVersion]: Model versions. + Model versions. """ mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() mlmd_options.filter_query = f"parent_contexts_a.id = {registered_model_id}" @@ -231,12 +231,12 @@ def get_model_version_by_params( Either fetches by using external ID or by using registered model ID and version. Args: - registered_model_id (str, optional): Registered model ID. - version (str, optional): Model version. - external_id (str, optional): Model version external ID. + registered_model_id: Registered model ID. + version: Model version. + external_id: Model version external ID. Returns: - ModelVersion: Model version. + Model version. """ if external_id is not None: proto_mv = self._store.get_context( @@ -265,11 +265,11 @@ def upsert_model_artifact( This updates the model_artifact instance passed in with new data from the servers. Args: - model_artifact (ModelArtifact): Model artifact to upsert. - model_version_id (str): ID of the model version this artifact will be associated to. + model_artifact: Model artifact to upsert. + model_version_id: ID of the model version this artifact will be associated to. Returns: - str: ID of the model artifact. + ID of the model artifact. """ mv_id = int(model_version_id) try: @@ -299,10 +299,10 @@ def get_model_artifact_by_id(self, id: str) -> ModelArtifact: """Fetch a model artifact by its ID. Args: - id (str): Model artifact ID. + id: Model artifact ID. Returns: - ModelArtifact: Model artifact. + Model artifact. """ proto_ma = self._store.get_artifact( ModelArtifact.get_proto_type_name(), int(id) @@ -315,11 +315,11 @@ def get_model_artifact_by_params( """Fetch a model artifact either by external ID or by the ID of its associated model version. Args: - model_version_id (str, optional): ID of the associated model version. - external_id (str, optional): Model artifact external ID. + model_version_id: ID of the associated model version. + external_id: Model artifact external ID. Returns: - ModelArtifact: Model artifact. + Model artifact. """ if external_id: proto_ma = self._store.get_artifact( @@ -342,11 +342,11 @@ def get_model_artifacts( """Fetches model artifacts. Args: - model_version_id (str, optional): ID of the associated model version. - options (ListOptions, optional): Options for listing model artifacts. + model_version_id: ID of the associated model version. + options: Options for listing model artifacts. Returns: - Sequence[ModelArtifact]: Model artifacts. + Model artifacts. """ mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() if model_version_id is not None: diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index 71ff8688..e007b8e7 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -36,7 +36,7 @@ def __init__(self, config: MetadataStoreClientConfig): """Constructor. Args: - config (MetadataStoreClientConfig): MLMD config. + config: MLMD config. """ self._mlmd_store = MetadataStore(config) @@ -44,11 +44,11 @@ def get_type_id(self, mlmd_pt: type[ProtoType], type_name: str) -> int: """Get backend ID for a type. Args: - mlmd_pt (ProtoType): Proto type. - type_name (str): Name of the type. + mlmd_pt: Proto type. + type_name: Name of the type. Returns: - int: Backend ID. + Backend ID. Raises: TypeNotFoundException: If the type doesn't exist. @@ -85,10 +85,10 @@ def put_artifact(self, artifact: Artifact) -> int: """Put an artifact in the store. Args: - artifact (Artifact): Artifact to put. + artifact: Artifact to put. Returns: - int: ID of the artifact. + ID of the artifact. Raises: DuplicateException: If an artifact with the same name or external id already exists. @@ -111,10 +111,10 @@ def put_context(self, context: Context) -> int: """Put a context in the store. Args: - context (Context): Context to put. + context: Context to put. Returns: - int: ID of the context. + ID of the context. Raises: DuplicateException: If a context with the same name or external id already exists. @@ -151,13 +151,13 @@ def get_context( If multiple arguments are provided, the simplest query will be performed. Args: - ctx_type_name (str): Name of the context type. - id (int, optional): ID of the context. - name (str, optional): Name of the context. - external_id (str, optional): External ID of the context. + ctx_type_name: Name of the context type. + id: ID of the context. + name: Name of the context. + external_id: External ID of the context. Returns: - Context: Context. + Context. Raises: StoreException: If the context doesn't exist. @@ -186,11 +186,11 @@ def get_contexts( """Get contexts from the store. Args: - ctx_type_name (str): Name of the context type. - options (ListOptions): List options. + ctx_type_name: Name of the context type. + options: List options. Returns: - Sequence[Context]: Contexts. + Contexts. """ # TODO: should we make options optional? # if options is not None: @@ -217,8 +217,8 @@ def put_context_parent(self, parent_id: int, child_id: int): """Put a parent-child relationship between two contexts. Args: - parent_id (int): ID of the parent context. - child_id (int): ID of the child context. + parent_id: ID of the parent context. + child_id: ID of the child context. Raises: StoreException: If the parent context doesn't exist. @@ -239,8 +239,8 @@ def put_attribution(self, context_id: int, artifact_id: int): """Put an attribution relationship between a context and an artifact. Args: - context_id (int): ID of the context. - artifact_id (int): ID of the artifact. + context_id: ID of the context. + artifact_id: ID of the artifact. Raises: StoreException: Invalid argument. @@ -272,13 +272,13 @@ def get_artifact( Gets an artifact either by ID, name or external ID. Args: - art_type_name (str): Name of the artifact type. - id (int, optional): ID of the artifact. - name (str, optional): Name of the artifact. - external_id (str, optional): External ID of the artifact. + art_type_name: Name of the artifact type. + id: ID of the artifact. + name: Name of the artifact. + external_id: External ID of the artifact. Returns: - Artifact: Artifact. + Artifact. Raises: StoreException: If the context doesn't exist. @@ -305,11 +305,11 @@ def get_attributed_artifact(self, art_type_name: str, ctx_id: int) -> Artifact: """Get an artifact from the store by its attributed context. Args: - art_type_name (str): Name of the artifact type. - ctx_id (int): ID of the context. + art_type_name: Name of the artifact type. + ctx_id: ID of the context. Returns: - Artifact: Artifact. + Artifact. """ try: artifacts = self._mlmd_store.get_artifacts_by_context(ctx_id) @@ -328,11 +328,11 @@ def get_artifacts( """Get artifacts from the store. Args: - art_type_name (str): Name of the artifact type. - options (ListOptions): List options. + art_type_name: Name of the artifact type. + options: List options. Returns: - Sequence[Artifact]: Artifacts. + Artifacts. """ try: artifacts = self._mlmd_store.get_artifacts(options) diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index fce6b4f5..3a5af508 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -40,9 +40,9 @@ class BaseArtifact(ProtoBase): """Abstract base class for all artifacts. Attributes: - name (str): Name of the artifact. - uri (str): URI of the artifact. - state (ArtifactState): State of the artifact. + name: Name of the artifact. + uri: URI of the artifact. + state: State of the artifact. """ name: str @@ -78,15 +78,15 @@ class ModelArtifact(BaseArtifact, Prefixable): """Represents a Model. Attributes: - name (str): Name of the model. - uri (str): URI of the model. - description (str, optional): Description of the object. - external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. - model_format_name (str, optional): Name of the model format. - model_format_version (str, optional): Version of the model format. - storage_key (str, optional): Storage secret name. - storage_path (str, optional): Storage path of the model. - service_account_name (str, optional): Name of the service account with storage secret. + name: Name of the model. + uri: URI of the model. + description: Description of the object. + external_id: Customizable ID. Has to be unique among instances of the same type. + model_format_name: Name of the model format. + model_format_version: Version of the model format. + storage_key: Storage secret name. + storage_path: Storage path of the model. + service_account_name: Name of the service account with storage secret. """ # TODO: this could be an enum of valid formats diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index 22e3f9aa..d110b1d0 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -20,7 +20,7 @@ def get_proto_type_name(cls) -> str: """Name of the proto type. Returns: - str: Name of the class prefixed with `odh.` + Name of the class prefixed with `odh.` """ return f"odh.{cls.__name__}" @@ -38,7 +38,7 @@ def map(self, type_id: int) -> ProtoType: type_id (int): ID of the type. Returns: - ProtoType: Proto object. + Proto object. """ pass @@ -48,10 +48,10 @@ def unmap(cls, mlmd_obj: ProtoType) -> Mappable: """Map from a proto object. Args: - mlmd_obj (ProtoType): Proto object. + mlmd_obj: Proto object. Returns: - Mappable: Python object. + Python object. """ pass @@ -78,12 +78,12 @@ class ProtoBase(Mappable, ABC): such as Artifacts, Contexts, and Executions. Attributes: - id (str): Protobuf object ID. Auto-assigned when put on the server. - name (str): Name of the object. - description (str, optional): Description of the object. - external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. - create_time_since_epoch (int): Seconds elapsed since object creation time, measured against epoch. - last_update_time_since_epoch (int): Seconds elapsed since object last update time, measured against epoch. + id: Protobuf object ID. Auto-assigned when put on the server. + name: Name of the object. + description: Description of the object. + external_id: Customizable ID. Has to be unique among instances of the same type. + create_time_since_epoch: Seconds elapsed since object creation time, measured against epoch. + last_update_time_since_epoch: Seconds elapsed since object last update time, measured against epoch. """ name: str = field(init=False) @@ -106,7 +106,7 @@ def get_proto_type(cls) -> type[ProtoType]: """Proto type associated with this class. Returns: - ProtoType: Proto type. + Proto type. """ pass @@ -117,8 +117,8 @@ def _map_props( """Map properties from Python to proto. Args: - py_props (dict[str, ScalarType]): Python properties. - mlmd_props (dict[str, Any]): Proto properties, will be modified in place. + py_props: Python properties. + mlmd_props: Proto properties, will be modified in place. """ for key, value in py_props.items(): if value is None: @@ -154,10 +154,10 @@ def _unmap_props(mlmd_props: dict[str, Any]) -> dict[str, ScalarType]: """Map properties from proto to Python. Args: - mlmd_props (dict[str, Any]): Proto properties. + mlmd_props: Proto properties. Returns: - dict[str, ScalarType]: Python properties. + Python properties. """ py_props: dict[str, ScalarType] = {} for key, value in mlmd_props.items(): diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 23d417dc..909c283e 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -38,14 +38,14 @@ class ModelVersion(BaseContext, Prefixable): """Represents a model version. Attributes: - model (ModelArtifact): Model associated with this version. - version (str): Version of the model. - author (str): Author of the model version. - description (str, optional): Description of the object. - external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. - artifacts (list[BaseArtifact]): Artifacts associated with this version. - tags (list[str]): Tags associated with this version. - metadata (dict[str, ScalarType]): Metadata associated with this version. + model: Model associated with this version. + version: Version of the model. + author: Author of the model version. + description: Description of the object. + external_id: Customizable ID. Has to be unique among instances of the same type. + artifacts: Artifacts associated with this version. + tags: Tags associated with this version. + metadata: Metadata associated with this version. """ model: ModelArtifact @@ -101,10 +101,10 @@ class RegisteredModel(BaseContext): """Represents a registered model. Attributes: - name (str): Registered model name. - description (str, optional): Description of the object. - external_id (str, optional): Customizable ID. Has to be unique among instances of the same type. - versions (list[ModelVersion]): Versions associated with this model. + name: Registered model name. + description: Description of the object. + external_id: Customizable ID. Has to be unique among instances of the same type. + versions: Versions associated with this model. """ name: str diff --git a/clients/python/src/model_registry/types/options.py b/clients/python/src/model_registry/types/options.py index 44b79824..3e4ef688 100644 --- a/clients/python/src/model_registry/types/options.py +++ b/clients/python/src/model_registry/types/options.py @@ -25,9 +25,9 @@ class ListOptions: """Options for listing objects. Attributes: - limit (int): Maximum number of objects to return. - order_by (OrderByField, optional): Field to order by. - is_asc (bool): Whether to order in ascending order. Defaults to True. + limit: Maximum number of objects to return. + order_by: Field to order by. + is_asc: Whether to order in ascending order. Defaults to True. """ limit: int | None = field(default=None) @@ -38,7 +38,7 @@ def as_mlmd_list_options(self) -> MLMDListOptions: """Convert to MLMD ListOptions. Returns: - ListOptions: MLMD ListOptions. + MLMD ListOptions. """ return MLMDListOptions( limit=self.limit, From 9e09b420fd55cc5b4a61aaacf8c9d8af9cdd1bb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 28 Nov 2023 08:21:26 +0000 Subject: [PATCH 163/254] build(deps): bump github.com/golang/glog from 1.1.2 to 1.2.0 (#202) --- go.mod | 2 +- go.sum | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index ad85c9d7..75f635db 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/go-chi/chi/v5 v5.0.10 github.com/go-chi/cors v1.2.1 - github.com/golang/glog v1.1.2 + github.com/golang/glog v1.2.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.17.0 diff --git a/go.sum b/go.sum index 032d60d5..23b99352 100644 --- a/go.sum +++ b/go.sum @@ -108,8 +108,8 @@ github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo= -github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ= +github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= +github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -150,8 +150,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= From 08396001314cd9a06d8a708d57c45ea706f2a9e2 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:13 -0300 Subject: [PATCH 164/254] py: add dev dependencies to pyproject Signed-off-by: Isabella Basso do Amaral --- clients/python/poetry.lock | 140 +++++++++++++++++++++++++++++++++- clients/python/pyproject.toml | 3 + 2 files changed, 142 insertions(+), 1 deletion(-) diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock index 5baa77ea..3e4e1632 100644 --- a/clients/python/poetry.lock +++ b/clients/python/poetry.lock @@ -456,6 +456,21 @@ dev = ["black", "flake8", "isort", "pre-commit", "pyproject-flake8"] doc = ["myst-parser", "sphinx", "sphinx-book-theme"] test = ["coverage", "pytest", "pytest-cov"] +[[package]] +name = "livereload" +version = "2.6.3" +description = "Python LiveReload is an awesome tool for web developers" +optional = false +python-versions = "*" +files = [ + {file = "livereload-2.6.3-py2.py3-none-any.whl", hash = "sha256:ad4ac6f53b2d62bb6ce1a5e6e96f1f00976a32348afedcb4b6d68df2a1d346e4"}, + {file = "livereload-2.6.3.tar.gz", hash = "sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"}, +] + +[package.dependencies] +six = "*" +tornado = {version = "*", markers = "python_version > \"2.7\""} + [[package]] name = "markdown-it-py" version = "3.0.0" @@ -604,6 +619,64 @@ grpcio = ">=1.8.6,<2" protobuf = ">=3.13,<4" six = ">=1.10,<2" +[[package]] +name = "mypy" +version = "1.7.1" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12cce78e329838d70a204293e7b29af9faa3ab14899aec397798a4b41be7f340"}, + {file = "mypy-1.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1484b8fa2c10adf4474f016e09d7a159602f3239075c7bf9f1627f5acf40ad49"}, + {file = "mypy-1.7.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31902408f4bf54108bbfb2e35369877c01c95adc6192958684473658c322c8a5"}, + {file = "mypy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f2c2521a8e4d6d769e3234350ba7b65ff5d527137cdcde13ff4d99114b0c8e7d"}, + {file = "mypy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:fcd2572dd4519e8a6642b733cd3a8cfc1ef94bafd0c1ceed9c94fe736cb65b6a"}, + {file = "mypy-1.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b901927f16224d0d143b925ce9a4e6b3a758010673eeded9b748f250cf4e8f7"}, + {file = "mypy-1.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2f7f6985d05a4e3ce8255396df363046c28bea790e40617654e91ed580ca7c51"}, + {file = "mypy-1.7.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:944bdc21ebd620eafefc090cdf83158393ec2b1391578359776c00de00e8907a"}, + {file = "mypy-1.7.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9c7ac372232c928fff0645d85f273a726970c014749b924ce5710d7d89763a28"}, + {file = "mypy-1.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:f6efc9bd72258f89a3816e3a98c09d36f079c223aa345c659622f056b760ab42"}, + {file = "mypy-1.7.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6dbdec441c60699288adf051f51a5d512b0d818526d1dcfff5a41f8cd8b4aaf1"}, + {file = "mypy-1.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4fc3d14ee80cd22367caaaf6e014494415bf440980a3045bf5045b525680ac33"}, + {file = "mypy-1.7.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c6e4464ed5f01dc44dc9821caf67b60a4e5c3b04278286a85c067010653a0eb"}, + {file = "mypy-1.7.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:d9b338c19fa2412f76e17525c1b4f2c687a55b156320acb588df79f2e6fa9fea"}, + {file = "mypy-1.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:204e0d6de5fd2317394a4eff62065614c4892d5a4d1a7ee55b765d7a3d9e3f82"}, + {file = "mypy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:84860e06ba363d9c0eeabd45ac0fde4b903ad7aa4f93cd8b648385a888e23200"}, + {file = "mypy-1.7.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8c5091ebd294f7628eb25ea554852a52058ac81472c921150e3a61cdd68f75a7"}, + {file = "mypy-1.7.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40716d1f821b89838589e5b3106ebbc23636ffdef5abc31f7cd0266db936067e"}, + {file = "mypy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5cf3f0c5ac72139797953bd50bc6c95ac13075e62dbfcc923571180bebb662e9"}, + {file = "mypy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:78e25b2fd6cbb55ddfb8058417df193f0129cad5f4ee75d1502248e588d9e0d7"}, + {file = "mypy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75c4d2a6effd015786c87774e04331b6da863fc3fc4e8adfc3b40aa55ab516fe"}, + {file = "mypy-1.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2643d145af5292ee956aa0a83c2ce1038a3bdb26e033dadeb2f7066fb0c9abce"}, + {file = "mypy-1.7.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75aa828610b67462ffe3057d4d8a4112105ed211596b750b53cbfe182f44777a"}, + {file = "mypy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ee5d62d28b854eb61889cde4e1dbc10fbaa5560cb39780c3995f6737f7e82120"}, + {file = "mypy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:72cf32ce7dd3562373f78bd751f73c96cfb441de147cc2448a92c1a308bd0ca6"}, + {file = "mypy-1.7.1-py3-none-any.whl", hash = "sha256:f7c5d642db47376a0cc130f0de6d055056e010debdaf0707cd2b0fc7e7ef30ea"}, + {file = "mypy-1.7.1.tar.gz", hash = "sha256:fcb6d9afb1b6208b4c712af0dafdc650f518836065df0d4fb1d800f5d6773db2"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + [[package]] name = "myst-parser" version = "2.0.0" @@ -823,6 +896,32 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "ruff" +version = "0.1.6" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.1.6-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:88b8cdf6abf98130991cbc9f6438f35f6e8d41a02622cc5ee130a02a0ed28703"}, + {file = "ruff-0.1.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5c549ed437680b6105a1299d2cd30e4964211606eeb48a0ff7a93ef70b902248"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cf5f701062e294f2167e66d11b092bba7af6a057668ed618a9253e1e90cfd76"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:05991ee20d4ac4bb78385360c684e4b417edd971030ab12a4fbd075ff535050e"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87455a0c1f739b3c069e2f4c43b66479a54dea0276dd5d4d67b091265f6fd1dc"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:683aa5bdda5a48cb8266fcde8eea2a6af4e5700a392c56ea5fb5f0d4bfdc0240"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:137852105586dcbf80c1717facb6781555c4e99f520c9c827bd414fac67ddfb6"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd98138a98d48a1c36c394fd6b84cd943ac92a08278aa8ac8c0fdefcf7138f35"}, + {file = "ruff-0.1.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a0cd909d25f227ac5c36d4e7e681577275fb74ba3b11d288aff7ec47e3ae745"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e8fd1c62a47aa88a02707b5dd20c5ff20d035d634aa74826b42a1da77861b5ff"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:fd89b45d374935829134a082617954120d7a1470a9f0ec0e7f3ead983edc48cc"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:491262006e92f825b145cd1e52948073c56560243b55fb3b4ecb142f6f0e9543"}, + {file = "ruff-0.1.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:ea284789861b8b5ca9d5443591a92a397ac183d4351882ab52f6296b4fdd5462"}, + {file = "ruff-0.1.6-py3-none-win32.whl", hash = "sha256:1610e14750826dfc207ccbcdd7331b6bd285607d4181df9c1c6ae26646d6848a"}, + {file = "ruff-0.1.6-py3-none-win_amd64.whl", hash = "sha256:4558b3e178145491e9bc3b2ee3c4b42f19d19384eaa5c59d10acf6e8f8b57e33"}, + {file = "ruff-0.1.6-py3-none-win_arm64.whl", hash = "sha256:03910e81df0d8db0e30050725a5802441c2022ea3ae4fe0609b76081731accbc"}, + {file = "ruff-0.1.6.tar.gz", hash = "sha256:1b09f29b16c6ead5ea6b097ef2764b42372aebe363722f1605ecbcd2b9207184"}, +] + [[package]] name = "six" version = "1.16.0" @@ -891,6 +990,25 @@ docs = ["sphinxcontrib-websupport"] lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools (>=67.0)"] +[[package]] +name = "sphinx-autobuild" +version = "2021.3.14" +description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." +optional = false +python-versions = ">=3.6" +files = [ + {file = "sphinx-autobuild-2021.3.14.tar.gz", hash = "sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"}, + {file = "sphinx_autobuild-2021.3.14-py3-none-any.whl", hash = "sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac"}, +] + +[package.dependencies] +colorama = "*" +livereload = "*" +sphinx = "*" + +[package.extras] +test = ["pytest", "pytest-cov"] + [[package]] name = "sphinx-basic-ng" version = "1.0.0b2" @@ -1023,6 +1141,26 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] +[[package]] +name = "tornado" +version = "6.3.3" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">= 3.8" +files = [ + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, + {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, + {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, + {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, + {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, + {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, + {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, +] + [[package]] name = "typing-extensions" version = "4.8.0" @@ -1082,4 +1220,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 3.11" -content-hash = "108d2d20b2ce4fe532e658c9ec604ed693f37e15b84400753949729a9cf9a3ba" +content-hash = "323e9f5ac3a2a98f69554c3e2d36f75112b75517faa70637fb94256f8052c5fc" diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 515eaff5..757b863d 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -19,6 +19,9 @@ myst-parser = { extras = ["linkify"], version = "^2.0.0" } pytest = "^7.4.2" coverage = { extras = ["toml"], version = "^7.3.2" } pytest-cov = "^4.1.0" +sphinx-autobuild = "^2021.3.14" +ruff = "^0.1.6" +mypy = "^1.7.0" [tool.coverage.run] branch = true From 4fc5f2e6be2a8b6e02177f9dcf5c77070335f484 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:13 -0300 Subject: [PATCH 165/254] py: noxfile: specify python versions for mypy and lint We also don't need to install the project to run ruff. Signed-off-by: Isabella Basso do Amaral --- clients/python/noxfile.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py index 695283d2..567ff348 100644 --- a/clients/python/noxfile.py +++ b/clients/python/noxfile.py @@ -30,16 +30,17 @@ @session(python=python_versions) def lint(session: Session) -> None: - """lint using ruff and mypy""" - session.install(".", "ruff") + """Lint using ruff.""" + session.install("ruff") session.run("ruff", "check", "src") -@session +@session(python=python_versions) def mypy(session: Session) -> None: - """lint using ruff and mypy""" - session.install(".", "mypy") + """Type check using mypy.""" + session.install(".") + session.install("mypy") session.run("mypy", "src") @@ -83,7 +84,7 @@ def docs_build(session: Session) -> None: args.insert(0, "--color") session.install(".") - session.install("sphinx", "furo", "myst-parser", "linkify-it-py") + session.install("sphinx", "myst-parser[linkify]", "furo") build_dir = Path("docs", "_build") if build_dir.exists(): @@ -97,9 +98,7 @@ def docs(session: Session) -> None: """Build and serve the documentation with live reloading on file changes.""" args = session.posargs or ["--open-browser", "docs", "docs/_build"] session.install(".") - session.install( - "sphinx", "furo", "myst-parser", "linkify-it-py", "sphinx-autobuild" - ) + session.install("sphinx", "myst-parser[linkify]", "furo", "sphinx-autobuild") build_dir = Path("docs", "_build") if build_dir.exists(): From a69543639f50e101459aadaac6a13c12bd870880 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 21 Nov 2023 15:36:13 -0300 Subject: [PATCH 166/254] gha: py: run lint and mypy as separate jobs Signed-off-by: Isabella Basso do Amaral --- .github/workflows/python-client.yml | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml index 5f5e8c52..4ffeb8c1 100644 --- a/.github/workflows/python-client.yml +++ b/.github/workflows/python-client.yml @@ -13,10 +13,11 @@ jobs: strategy: fail-fast: false matrix: + python: ["3.10"] + session: [lint, tests, mypy, docs-build] include: - - { python: "3.10", session: "tests" } - - { python: "3.9", session: "tests" } - - { python: "3.10", session: "docs-build" } + - python: "3.9" + session: tests env: NOXSESSION: ${{ matrix.session }} @@ -57,21 +58,14 @@ jobs: pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry nox --version - - name: Lint - working-directory: clients/python - if: matrix.session == 'tests' - run: | - nox --python=${{ matrix.python }} -s lint - nox --python=${{ matrix.python }} -s mypy || failure=true - if [[ -n $failure ]]; then - echo "::error title='mypy failure'::Check the logs for more details" - fi - - name: Run Nox working-directory: clients/python run: | if [[ ${{ matrix.session }} == "tests" ]]; then - nox --python=${{ matrix.python }} -s tests -- --cov-report=xml + nox --python=${{ matrix.python }} -- --cov-report=xml + elif [[ ${{ matrix.session }} == "mypy" ]]; then + nox --python=${{ matrix.python }} ||\ + echo "::error title='mypy failure'::Check the logs for more details" else nox --python=${{ matrix.python }} fi From cf20780521ef2b58d1fe7d846e486935bdae319a Mon Sep 17 00:00:00 2001 From: tarilabs Date: Tue, 28 Nov 2023 09:06:09 +0100 Subject: [PATCH 167/254] Align MLMD Properties for Artifact --- .../src/model_registry/types/artifacts.py | 20 +++++++++---------- clients/python/tests/test_client.py | 10 +++++----- .../tests/types/test_artifact_mapping.py | 10 +++++----- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index 3a5af508..b4c4a699 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -107,11 +107,11 @@ def mlmd_name_prefix(self) -> str: def map(self, type_id: int) -> Artifact: mlmd_obj = super().map(type_id) props = { - "modelFormatName": self.model_format_name, - "modelFormatVersion": self.model_format_version, - "storageKey": self.storage_key, - "storagePath": self.storage_path, - "serviceAccountName": self.service_account_name, + "model_format_name": self.model_format_name, + "model_format_version": self.model_format_version, + "storage_key": self.storage_key, + "storage_path": self.storage_path, + "service_account_name": self.service_account_name, } self._map_props(props, mlmd_obj.properties) return mlmd_obj @@ -123,13 +123,13 @@ def unmap(cls, mlmd_obj: Artifact) -> ModelArtifact: assert isinstance( py_obj, ModelArtifact ), f"Expected ModelArtifact, got {type(py_obj)}" - py_obj.model_format_name = mlmd_obj.properties["modelFormatName"].string_value + py_obj.model_format_name = mlmd_obj.properties["model_format_name"].string_value py_obj.model_format_version = mlmd_obj.properties[ - "modelFormatVersion" + "model_format_version" ].string_value - py_obj.storage_key = mlmd_obj.properties["storageKey"].string_value - py_obj.storage_path = mlmd_obj.properties["storagePath"].string_value + py_obj.storage_key = mlmd_obj.properties["storage_key"].string_value + py_obj.storage_path = mlmd_obj.properties["storage_path"].string_value py_obj.service_account_name = mlmd_obj.properties[ - "serviceAccountName" + "service_account_name" ].string_value return py_obj diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index e55721b3..a43b5408 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -32,11 +32,11 @@ def model(store_wrapper: MLMDStore) -> Mapped: art_type.name = ModelArtifact.get_proto_type_name() props = [ "description", - "modelFormatName", - "modelFormatVersion", - "storageKey", - "storagePath", - "serviceAccountName", + "model_format_name", + "model_format_version", + "storage_key", + "storage_path", + "service_account_name", ] for key in props: art_type.properties[key] = metadata_store_pb2.STRING diff --git a/clients/python/tests/types/test_artifact_mapping.py b/clients/python/tests/types/test_artifact_mapping.py index 635a4c0e..f1e45b9d 100644 --- a/clients/python/tests/types/test_artifact_mapping.py +++ b/clients/python/tests/types/test_artifact_mapping.py @@ -20,11 +20,11 @@ def complete_model() -> Mapped: proto_model.state = Artifact.UNKNOWN proto_model.uri = "test_uri" proto_model.properties["description"].string_value = "test description" - proto_model.properties["modelFormatName"].string_value = "test_format" - proto_model.properties["modelFormatVersion"].string_value = "test_format_version" - proto_model.properties["storageKey"].string_value = "test_storage_key" - proto_model.properties["storagePath"].string_value = "test_storage_path" - proto_model.properties["serviceAccountName"].string_value = "test_account_name" + proto_model.properties["model_format_name"].string_value = "test_format" + proto_model.properties["model_format_version"].string_value = "test_format_version" + proto_model.properties["storage_key"].string_value = "test_storage_key" + proto_model.properties["storage_path"].string_value = "test_storage_path" + proto_model.properties["service_account_name"].string_value = "test_account_name" py_model = ModelArtifact( "test_model", From 5940bdd39f1aa7f5fca5672e15f4bb9831180cd4 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Tue, 28 Nov 2023 19:35:53 +0100 Subject: [PATCH 168/254] Align author in OpenAPI and Core layer (#189) * Align author in OpenAPI and Core layer * Ignore author in OverrideNotEditableForModelVersion as it is an editable field --------- Co-authored-by: Andrea Lamparelli --- api/openapi/model-registry.yaml | 3 + .../generated/mlmd_openapi_converter.gen.go | 1 + .../generated/openapi_converter.gen.go | 12 + .../converter/mlmd_converter_util_test.go | 2 + internal/converter/mlmd_openapi_converter.go | 1 + .../converter/mlmd_openapi_converter_util.go | 4 + internal/converter/opeanpi_converter.go | 2 +- .../converter/openapi_mlmd_converter_util.go | 11 +- pkg/core/core_test.go | 263 +++++++----------- pkg/openapi/model_model_version.go | 37 +++ pkg/openapi/model_model_version_create.go | 37 +++ pkg/openapi/model_model_version_update.go | 37 +++ 12 files changed, 234 insertions(+), 176 deletions(-) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index 3d667975..dc3698fd 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -1167,6 +1167,9 @@ components: properties: state: $ref: '#/components/schemas/ModelVersionState' + author: + description: Name of the author. + type: string BaseArtifactCreate: allOf: - diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index 2b110d4b..d6e5c4cf 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -99,6 +99,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertModelVersion(source *proto.Context) openapiModelVersion.ExternalID = pString openapiModelVersion.Name = converter.MapNameFromOwned((*source).Name) openapiModelVersion.State = converter.MapModelVersionState(source) + openapiModelVersion.Author = converter.MapPropertyAuthor((*source).Properties) openapiModelVersion.Id = converter.Int64ToString((*source).Id) openapiModelVersion.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) openapiModelVersion.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index f1334c9f..17f14917 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -296,6 +296,12 @@ func (c *OpenAPIConverterImpl) ConvertModelVersionCreate(source *openapi.ModelVe pOpenapiModelVersionState = &openapiModelVersionState } openapiModelVersion.State = pOpenapiModelVersionState + var pString4 *string + if (*source).Author != nil { + xstring4 := *(*source).Author + pString4 = &xstring4 + } + openapiModelVersion.Author = pString4 pOpenapiModelVersion = &openapiModelVersion } return pOpenapiModelVersion, nil @@ -331,6 +337,12 @@ func (c *OpenAPIConverterImpl) ConvertModelVersionUpdate(source *openapi.ModelVe pOpenapiModelVersionState = &openapiModelVersionState } openapiModelVersion.State = pOpenapiModelVersionState + var pString3 *string + if (*source).Author != nil { + xstring3 := *(*source).Author + pString3 = &xstring3 + } + openapiModelVersion.Author = pString3 pOpenapiModelVersion = &openapiModelVersion } return pOpenapiModelVersion, nil diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index 72a50b5b..318c4e29 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -220,12 +220,14 @@ func TestMapModelVersionProperties(t *testing.T) { Model: &openapi.ModelVersion{ Name: of("v1"), Description: of("my model version description"), + Author: of("John Doe"), }, }) assertion.Nil(err) assertion.Equal(4, len(props)) assertion.Equal("my model version description", props["description"].GetStringValue()) assertion.Equal("v1", props["version"].GetStringValue()) + assertion.Equal("John Doe", props["author"].GetStringValue()) } func TestMapModelVersionType(t *testing.T) { diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index be7d2b46..a9370186 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -21,6 +21,7 @@ type MLMDToOpenAPIConverter interface { // goverter:map Name | MapNameFromOwned // goverter:map Properties Description | MapDescription // goverter:map . State | MapModelVersionState + // goverter:map Properties Author | MapPropertyAuthor ConvertModelVersion(source *proto.Context) (*openapi.ModelVersion, error) // goverter:map Name | MapNameFromOwned diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index b99f5fe8..11bdf016 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -75,6 +75,10 @@ func MapNameFromOwned(source *string) *string { // MODEL VERSION +func MapPropertyAuthor(properties map[string]*proto.Value) *string { + return MapStringProperty(properties, "author") +} + // MODEL ARTIFACT func MapArtifactType(source *proto.Artifact) (string, error) { diff --git a/internal/converter/opeanpi_converter.go b/internal/converter/opeanpi_converter.go index 230fc2e4..9e6b2e0f 100644 --- a/internal/converter/opeanpi_converter.go +++ b/internal/converter/opeanpi_converter.go @@ -58,7 +58,7 @@ type OpenAPIConverter interface { // Ignore all fields that ARE editable // goverter:default InitModelVersionWithUpdate // goverter:autoMap Existing - // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties State + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties State Author OverrideNotEditableForModelVersion(source OpenapiUpdateWrapper[openapi.ModelVersion]) (openapi.ModelVersion, error) // Ignore all fields that ARE editable diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index e65e604f..e33dfa48 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -180,11 +180,12 @@ func MapModelVersionProperties(source *OpenAPIModelWrapper[openapi.ModelVersion] } } - // TODO: not available for now - props["author"] = &proto.Value{ - Value: &proto.Value_StringValue{ - StringValue: "", - }, + if (*source.Model).Author != nil { + props["author"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *(*source.Model).Author, + }, + } } } return props, nil diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index db4aba1e..f0c2458b 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -19,6 +19,7 @@ var ( // generic ascOrderDirection string descOrderDirection string + customString string // registered models modelName string modelDescription string @@ -53,6 +54,7 @@ func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataSt // initialize test variable before each test ascOrderDirection = "ASC" descOrderDirection = "DESC" + customString = "this is a customString value" modelName = "MyAwesomeModel" modelDescription = "reg model description" modelExternalId = "org.myawesomemodel" @@ -160,13 +162,7 @@ func registerModelVersion( Name: &modelVersionName, ExternalID: &versionExternalId, Description: &modelVersionDescription, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } if overrideVersionName != nil { @@ -977,13 +973,7 @@ func TestCreateModelVersion(t *testing.T) { ExternalID: &versionExternalId, Description: &modelVersionDescription, State: &state, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) @@ -1004,7 +994,7 @@ func TestCreateModelVersion(t *testing.T) { assertion.Equal(*createdVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") assertion.Equal(versionExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") assertion.Equal(modelVersionDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") assertion.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) @@ -1026,13 +1016,7 @@ func TestCreateModelVersionFailure(t *testing.T) { modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } _, err := service.UpsertModelVersion(modelVersion, nil) @@ -1056,13 +1040,7 @@ func TestUpdateModelVersion(t *testing.T) { modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) @@ -1098,7 +1076,7 @@ func TestUpdateModelVersion(t *testing.T) { assertion.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) @@ -1128,7 +1106,7 @@ func TestUpdateModelVersion(t *testing.T) { assertion.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) } @@ -1145,13 +1123,7 @@ func TestUpdateModelVersionFailure(t *testing.T) { modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) @@ -1189,13 +1161,7 @@ func TestGetModelVersionById(t *testing.T) { Name: &modelVersionName, ExternalID: &versionExternalId, State: &state, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) @@ -1219,7 +1185,7 @@ func TestGetModelVersionById(t *testing.T) { assertion.Equal(*modelVersion.Name, *getById.Name, "saved model name should match the provided one") assertion.Equal(*modelVersion.ExternalID, *getById.ExternalID, "saved external id should match the provided one") assertion.Equal(*modelVersion.State, *getById.State, "saved model state should match the original one") - assertion.Equal(author, *(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") + assertion.Equal(*getById.Author, author, "saved author property should match the provided one") } func TestGetModelVersionByParamsWithNoResults(t *testing.T) { @@ -1248,13 +1214,7 @@ func TestGetModelVersionByParamsName(t *testing.T) { modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) @@ -1277,7 +1237,7 @@ func TestGetModelVersionByParamsName(t *testing.T) { assertion.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned model version id should match the mlmd context one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByName.Name), *ctx.Name, "saved model name should match the provided one") assertion.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByName.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") + assertion.Equal(ctx.Properties["author"].GetStringValue(), *getByName.Author, "saved author property should match the provided one") } func TestGetModelVersionByParamsExternalId(t *testing.T) { @@ -1292,13 +1252,7 @@ func TestGetModelVersionByParamsExternalId(t *testing.T) { modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) @@ -1321,7 +1275,7 @@ func TestGetModelVersionByParamsExternalId(t *testing.T) { assertion.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned model version id should match the mlmd context one") assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByExternalId.Name), *ctx.Name, "saved model name should match the provided one") assertion.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByExternalId.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") + assertion.Equal(ctx.Properties["author"].GetStringValue(), *getByExternalId.Author, "saved author property should match the provided one") } func TestGetModelVersionByEmptyParams(t *testing.T) { @@ -1336,13 +1290,7 @@ func TestGetModelVersionByEmptyParams(t *testing.T) { modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, ExternalID: &versionExternalId, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) @@ -1475,9 +1423,9 @@ func TestCreateModelArtifact(t *testing.T) { StorageKey: of("aws-connection-models"), StoragePath: of("bucket"), CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1496,7 +1444,7 @@ func TestCreateModelArtifact(t *testing.T) { assertion.Equal("1", *createdArtifact.ModelFormatVersion) assertion.Equal("aws-connection-models", *createdArtifact.StorageKey) assertion.Equal("bucket", *createdArtifact.StoragePath) - assertion.Equal(author, *(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue) + assertion.Equal(customString, *(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) getById, err := client.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ @@ -1513,7 +1461,7 @@ func TestCreateModelArtifact(t *testing.T) { assertion.Equal(*createdArtifact.ModelFormatVersion, getById.Artifacts[0].Properties["model_format_version"].GetStringValue()) assertion.Equal(*createdArtifact.StorageKey, getById.Artifacts[0].Properties["storage_key"].GetStringValue()) assertion.Equal(*createdArtifact.StoragePath, getById.Artifacts[0].Properties["storage_path"].GetStringValue()) - assertion.Equal(*(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["author"].GetStringValue()) + assertion.Equal(*(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) modelVersionIdAsInt, _ := converter.StringToInt64(&modelVersionId) byCtx, _ := client.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ @@ -1537,9 +1485,9 @@ func TestCreateModelArtifactFailure(t *testing.T) { State: (*openapi.ArtifactState)(&artifactState), Uri: &artifactUri, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1568,9 +1516,9 @@ func TestUpdateModelArtifact(t *testing.T) { State: (*openapi.ArtifactState)(&artifactState), Uri: &artifactUri, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1597,7 +1545,7 @@ func TestUpdateModelArtifact(t *testing.T) { assertion.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) assertion.Equal(string(newState), getById.Artifacts[0].State.String()) assertion.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) - assertion.Equal(*(*createdArtifact.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["author"].GetStringValue()) + assertion.Equal(*(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) } func TestUpdateModelArtifactFailure(t *testing.T) { @@ -1614,9 +1562,9 @@ func TestUpdateModelArtifactFailure(t *testing.T) { State: (*openapi.ArtifactState)(&artifactState), Uri: &artifactUri, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1652,9 +1600,9 @@ func TestGetModelArtifactById(t *testing.T) { State: (*openapi.ArtifactState)(&artifactState), Uri: &artifactUri, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1673,7 +1621,7 @@ func TestGetModelArtifactById(t *testing.T) { assertion.Equal(artifactName, *getById.Name) assertion.Equal(*state, *getById.State) assertion.Equal(artifactUri, *getById.Uri) - assertion.Equal(author, *(*getById.CustomProperties)["author"].MetadataStringValue.StringValue) + assertion.Equal(customString, *(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) assertion.Equal(*createdArtifact, *getById, "artifacts returned during creation and on get by id should be equal") } @@ -1693,9 +1641,9 @@ func TestGetModelArtifactByParams(t *testing.T) { Uri: &artifactUri, ExternalID: &artifactExtId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1716,7 +1664,7 @@ func TestGetModelArtifactByParams(t *testing.T) { assertion.Equal(artifactExtId, *getByName.ExternalID) assertion.Equal(*state, *getByName.State) assertion.Equal(artifactUri, *getByName.Uri) - assertion.Equal(author, *(*getByName.CustomProperties)["author"].MetadataStringValue.StringValue) + assertion.Equal(customString, *(*getByName.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) assertion.Equal(*createdArtifact, *getByName, "artifacts returned during creation and on get by name should be equal") @@ -1728,7 +1676,7 @@ func TestGetModelArtifactByParams(t *testing.T) { assertion.Equal(artifactExtId, *getByExtId.ExternalID) assertion.Equal(*state, *getByExtId.State) assertion.Equal(artifactUri, *getByExtId.Uri) - assertion.Equal(author, *(*getByExtId.CustomProperties)["author"].MetadataStringValue.StringValue) + assertion.Equal(customString, *(*getByExtId.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) assertion.Equal(*createdArtifact, *getByExtId, "artifacts returned during creation and on get by ext id should be equal") } @@ -1748,9 +1696,9 @@ func TestGetModelArtifactByEmptyParams(t *testing.T) { Uri: &artifactUri, ExternalID: &artifactExtId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1793,9 +1741,9 @@ func TestGetModelArtifacts(t *testing.T) { Uri: &artifactUri, ExternalID: &artifactExtId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1810,9 +1758,9 @@ func TestGetModelArtifacts(t *testing.T) { Uri: &secondArtifactUri, ExternalID: &secondArtifactExtId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -1827,9 +1775,9 @@ func TestGetModelArtifacts(t *testing.T) { Uri: &thirdArtifactUri, ExternalID: &thirdArtifactExtId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2312,9 +2260,9 @@ func TestCreateInferenceService(t *testing.T) { Runtime: &runtime, State: &state, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2338,7 +2286,7 @@ func TestCreateInferenceService(t *testing.T) { assertion.Equal(*createdEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, entityName), *byId.Contexts[0].Name, "saved name should match the provided one") assertion.Equal(entityExternalId2, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") assertion.Equal(entityDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") assertion.Equal(runtime, byId.Contexts[0].Properties["runtime"].GetStringValue(), "saved runtime should match the provided one") assertion.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") @@ -2362,9 +2310,9 @@ func TestCreateInferenceServiceFailure(t *testing.T) { ServingEnvironmentId: "9999", RegisteredModelId: "9998", CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2399,9 +2347,9 @@ func TestUpdateInferenceService(t *testing.T) { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2441,7 +2389,7 @@ func TestUpdateInferenceService(t *testing.T) { assertion.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) @@ -2470,7 +2418,7 @@ func TestUpdateInferenceService(t *testing.T) { assertion.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].CustomProperties["author"].GetStringValue(), "saved author custom property should match the provided one") + assertion.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) @@ -2500,9 +2448,9 @@ func TestUpdateInferenceServiceFailure(t *testing.T) { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2549,9 +2497,9 @@ func TestGetInferenceServiceById(t *testing.T) { RegisteredModelId: registeredModelId, State: &state, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2578,7 +2526,7 @@ func TestGetInferenceServiceById(t *testing.T) { assertion.Equal(*eut.Name, *getById.Name, "saved name should match the provided one") assertion.Equal(*eut.ExternalID, *getById.ExternalID, "saved external id should match the provided one") assertion.Equal(*eut.State, *getById.State, "saved state should match the provided one") - assertion.Equal(*(*getById.CustomProperties)["author"].MetadataStringValue.StringValue, author, "saved author custom property should match the provided one") + assertion.Equal(*(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, customString, "saved custom_string_prop custom property should match the provided one") } func TestGetRegisteredModelByInferenceServiceId(t *testing.T) { @@ -2598,9 +2546,9 @@ func TestGetRegisteredModelByInferenceServiceId(t *testing.T) { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2647,9 +2595,9 @@ func TestGetModelVersionByInferenceServiceId(t *testing.T) { RegisteredModelId: registeredModelId, ModelVersionId: nil, // first we test by unspecified CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2703,9 +2651,9 @@ func TestGetInferenceServiceByParamsName(t *testing.T) { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2731,7 +2679,7 @@ func TestGetInferenceServiceByParamsName(t *testing.T) { assertion.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned id should match the mlmd context one") assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByName.Name), *ctx.Name, "saved name should match the provided one") assertion.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByName.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") + assertion.Equal(ctx.CustomProperties["custom_string_prop"].GetStringValue(), *(*getByName.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, "saved custom_string_prop custom property should match the provided one") } func TestGetInfernenceServiceByParamsExternalId(t *testing.T) { @@ -2751,9 +2699,9 @@ func TestGetInfernenceServiceByParamsExternalId(t *testing.T) { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2779,7 +2727,7 @@ func TestGetInfernenceServiceByParamsExternalId(t *testing.T) { assertion.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned id should match the mlmd context one") assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByExternalId.Name), *ctx.Name, "saved name should match the provided one") assertion.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.CustomProperties["author"].GetStringValue(), *(*getByExternalId.CustomProperties)["author"].MetadataStringValue.StringValue, "saved author custom property should match the provided one") + assertion.Equal(ctx.CustomProperties["custom_string_prop"].GetStringValue(), *(*getByExternalId.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, "saved custom_string_prop custom property should match the provided one") } func TestGetInferenceServiceByEmptyParams(t *testing.T) { @@ -2799,9 +2747,9 @@ func TestGetInferenceServiceByEmptyParams(t *testing.T) { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2942,13 +2890,7 @@ func TestCreateServeModel(t *testing.T) { Name: &modelVersionName, ExternalID: &versionExternalId, Description: &modelVersionDescription, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) assertion.Nilf(err, "error creating new model version for %d", registeredModelId) @@ -2963,9 +2905,9 @@ func TestCreateServeModel(t *testing.T) { Name: &entityName, ModelVersionId: createdVersionId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -2980,7 +2922,7 @@ func TestCreateServeModel(t *testing.T) { assertion.Equal(*state, *createdEntity.LastKnownState) assertion.Equal(createdVersionId, createdEntity.ModelVersionId) assertion.Equal(entityDescription, *createdEntity.Description) - assertion.Equal(author, *(*createdEntity.CustomProperties)["author"].MetadataStringValue.StringValue) + assertion.Equal(customString, *(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getById, err := client.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ @@ -2993,7 +2935,7 @@ func TestCreateServeModel(t *testing.T) { assertion.Equal(string(*createdEntity.LastKnownState), getById.Executions[0].LastKnownState.String()) assertion.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) assertion.Equal(*createdEntity.Description, getById.Executions[0].Properties["description"].GetStringValue()) - assertion.Equal(*(*createdEntity.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["author"].GetStringValue()) + assertion.Equal(*(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["custom_string_prop"].GetStringValue()) inferenceServiceIdAsInt, _ := converter.StringToInt64(&inferenceServiceId) byCtx, _ := client.GetExecutionsByContext(context.Background(), &proto.GetExecutionsByContextRequest{ @@ -3021,9 +2963,9 @@ func TestCreateServeModelFailure(t *testing.T) { Name: &entityName, ModelVersionId: "9998", CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -3052,13 +2994,7 @@ func TestUpdateServeModel(t *testing.T) { Name: &modelVersionName, ExternalID: &versionExternalId, Description: &modelVersionDescription, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) assertion.Nilf(err, "error creating new model version for %d", registeredModelId) @@ -3073,9 +3009,9 @@ func TestUpdateServeModel(t *testing.T) { Name: &entityName, ModelVersionId: createdVersionId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -3102,14 +3038,13 @@ func TestUpdateServeModel(t *testing.T) { assertion.Equal(fmt.Sprintf("%s:%s", inferenceServiceId, *createdEntity.Name), *getById.Executions[0].Name) assertion.Equal(string(newState), getById.Executions[0].LastKnownState.String()) assertion.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) - assertion.Equal(*(*createdEntity.CustomProperties)["author"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["author"].GetStringValue()) + assertion.Equal(*(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["custom_string_prop"].GetStringValue()) prevModelVersionId := updatedEntity.ModelVersionId updatedEntity.ModelVersionId = "" updatedEntity, err = service.UpsertServeModel(updatedEntity, &inferenceServiceId) assertion.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) assertion.Equal(prevModelVersionId, updatedEntity.ModelVersionId) - } func TestUpdateServeModelFailure(t *testing.T) { @@ -3126,13 +3061,7 @@ func TestUpdateServeModelFailure(t *testing.T) { Name: &modelVersionName, ExternalID: &versionExternalId, Description: &modelVersionDescription, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) assertion.Nilf(err, "error creating new model version for %d", registeredModelId) @@ -3146,9 +3075,9 @@ func TestUpdateServeModelFailure(t *testing.T) { Name: &entityName, ModelVersionId: createdVersionId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -3184,13 +3113,7 @@ func TestGetServeModelById(t *testing.T) { Name: &modelVersionName, ExternalID: &versionExternalId, Description: &modelVersionDescription, - CustomProperties: &map[string]openapi.MetadataValue{ - "author": { - MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, - }, - }, - }, + Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) assertion.Nilf(err, "error creating new model version for %d", registeredModelId) @@ -3204,9 +3127,9 @@ func TestGetServeModelById(t *testing.T) { Name: &entityName, ModelVersionId: createdVersionId, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -3223,7 +3146,7 @@ func TestGetServeModelById(t *testing.T) { assertion.Equal(entityName, *getById.Name) assertion.Equal(*state, *getById.LastKnownState) assertion.Equal(createdVersionId, getById.ModelVersionId) - assertion.Equal(author, *(*getById.CustomProperties)["author"].MetadataStringValue.StringValue) + assertion.Equal(customString, *(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) assertion.Equal(*createdEntity, *getById, "artifacts returned during creation and on get by id should be equal") } @@ -3264,9 +3187,9 @@ func TestGetServeModels(t *testing.T) { Name: &eut1Name, ModelVersionId: createdVersion1Id, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -3279,9 +3202,9 @@ func TestGetServeModels(t *testing.T) { Name: &eut2Name, ModelVersionId: createdVersion2Id, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, @@ -3294,9 +3217,9 @@ func TestGetServeModels(t *testing.T) { Name: &eut3Name, ModelVersionId: createdVersion3Id, CustomProperties: &map[string]openapi.MetadataValue{ - "author": { + "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ - StringValue: &author, + StringValue: &customString, }, }, }, diff --git a/pkg/openapi/model_model_version.go b/pkg/openapi/model_model_version.go index 1687774f..ee21bbbb 100644 --- a/pkg/openapi/model_model_version.go +++ b/pkg/openapi/model_model_version.go @@ -28,6 +28,8 @@ type ModelVersion struct { // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. Name *string `json:"name,omitempty"` State *ModelVersionState `json:"state,omitempty"` + // Name of the author. + Author *string `json:"author,omitempty"` // Output only. The unique server generated id of the resource. Id *string `json:"id,omitempty"` // Output only. Create time of the resource in millisecond since epoch. @@ -217,6 +219,38 @@ func (o *ModelVersion) SetState(v ModelVersionState) { o.State = &v } +// GetAuthor returns the Author field value if set, zero value otherwise. +func (o *ModelVersion) GetAuthor() string { + if o == nil || IsNil(o.Author) { + var ret string + return ret + } + return *o.Author +} + +// GetAuthorOk returns a tuple with the Author field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersion) GetAuthorOk() (*string, bool) { + if o == nil || IsNil(o.Author) { + return nil, false + } + return o.Author, true +} + +// HasAuthor returns a boolean if a field has been set. +func (o *ModelVersion) HasAuthor() bool { + if o != nil && !IsNil(o.Author) { + return true + } + + return false +} + +// SetAuthor gets a reference to the given string and assigns it to the Author field. +func (o *ModelVersion) SetAuthor(v string) { + o.Author = &v +} + // GetId returns the Id field value if set, zero value otherwise. func (o *ModelVersion) GetId() string { if o == nil || IsNil(o.Id) { @@ -338,6 +372,9 @@ func (o ModelVersion) ToMap() (map[string]interface{}, error) { if !IsNil(o.State) { toSerialize["state"] = o.State } + if !IsNil(o.Author) { + toSerialize["author"] = o.Author + } if !IsNil(o.Id) { toSerialize["id"] = o.Id } diff --git a/pkg/openapi/model_model_version_create.go b/pkg/openapi/model_model_version_create.go index 9908ad52..d825deeb 100644 --- a/pkg/openapi/model_model_version_create.go +++ b/pkg/openapi/model_model_version_create.go @@ -30,6 +30,8 @@ type ModelVersionCreate struct { // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. Name *string `json:"name,omitempty"` State *ModelVersionState `json:"state,omitempty"` + // Name of the author. + Author *string `json:"author,omitempty"` } // NewModelVersionCreate instantiates a new ModelVersionCreate object @@ -237,6 +239,38 @@ func (o *ModelVersionCreate) SetState(v ModelVersionState) { o.State = &v } +// GetAuthor returns the Author field value if set, zero value otherwise. +func (o *ModelVersionCreate) GetAuthor() string { + if o == nil || IsNil(o.Author) { + var ret string + return ret + } + return *o.Author +} + +// GetAuthorOk returns a tuple with the Author field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionCreate) GetAuthorOk() (*string, bool) { + if o == nil || IsNil(o.Author) { + return nil, false + } + return o.Author, true +} + +// HasAuthor returns a boolean if a field has been set. +func (o *ModelVersionCreate) HasAuthor() bool { + if o != nil && !IsNil(o.Author) { + return true + } + + return false +} + +// SetAuthor gets a reference to the given string and assigns it to the Author field. +func (o *ModelVersionCreate) SetAuthor(v string) { + o.Author = &v +} + func (o ModelVersionCreate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -263,6 +297,9 @@ func (o ModelVersionCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.State) { toSerialize["state"] = o.State } + if !IsNil(o.Author) { + toSerialize["author"] = o.Author + } return toSerialize, nil } diff --git a/pkg/openapi/model_model_version_update.go b/pkg/openapi/model_model_version_update.go index 3bc7ca7d..26ac9fe5 100644 --- a/pkg/openapi/model_model_version_update.go +++ b/pkg/openapi/model_model_version_update.go @@ -26,6 +26,8 @@ type ModelVersionUpdate struct { // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. ExternalID *string `json:"externalID,omitempty"` State *ModelVersionState `json:"state,omitempty"` + // Name of the author. + Author *string `json:"author,omitempty"` } // NewModelVersionUpdate instantiates a new ModelVersionUpdate object @@ -177,6 +179,38 @@ func (o *ModelVersionUpdate) SetState(v ModelVersionState) { o.State = &v } +// GetAuthor returns the Author field value if set, zero value otherwise. +func (o *ModelVersionUpdate) GetAuthor() string { + if o == nil || IsNil(o.Author) { + var ret string + return ret + } + return *o.Author +} + +// GetAuthorOk returns a tuple with the Author field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *ModelVersionUpdate) GetAuthorOk() (*string, bool) { + if o == nil || IsNil(o.Author) { + return nil, false + } + return o.Author, true +} + +// HasAuthor returns a boolean if a field has been set. +func (o *ModelVersionUpdate) HasAuthor() bool { + if o != nil && !IsNil(o.Author) { + return true + } + + return false +} + +// SetAuthor gets a reference to the given string and assigns it to the Author field. +func (o *ModelVersionUpdate) SetAuthor(v string) { + o.Author = &v +} + func (o ModelVersionUpdate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -199,6 +233,9 @@ func (o ModelVersionUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.State) { toSerialize["state"] = o.State } + if !IsNil(o.Author) { + toSerialize["author"] = o.Author + } return toSerialize, nil } From 0b314cde795c255adf83e78cc18916f8666aa6a4 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 28 Nov 2023 18:17:41 -0300 Subject: [PATCH 169/254] py: use plain model_name on MV Stop managing ModelArtifact on ModelVersion. This also allows us to simplify tests. Related: #206 Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 8 +- clients/python/src/model_registry/client.py | 28 +++---- .../src/model_registry/types/contexts.py | 9 ++- clients/python/tests/test_client.py | 77 ++----------------- .../tests/types/test_context_mapping.py | 28 ++++--- 5 files changed, 34 insertions(+), 116 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index d4eca55b..ccf7cfb8 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -68,9 +68,6 @@ To query objects using IDs, do ```py another_model = registry.get_registered_model_by_id("another-model-id") -# fetching a registered_model will also fetch its associated versions -versions = another_model.versions - another_version = registry.get_model_version_by_id("another-version-id", another_model.id) # fetching a version will also fetch its associated model artifact @@ -134,10 +131,7 @@ models = registry.get_registered_models() versions = registry.get_model_versions("registered_model_id") -# We can get associated model artifacts with the versions -model_artifacts = [version.model for version in versions] - -# We can also get a list of all model artifacts +# We can get a list of all model artifacts all_model_artifacts = registry.get_model_artifacts() ``` diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 868b4224..41f74e75 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -185,19 +185,15 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: Returns: Model version. """ - py_mv = ModelVersion.unmap( + return ModelVersion.unmap( self._store.get_context( ModelVersion.get_proto_type_name(), id=int(model_version_id) ) ) - py_mv.model = self.get_model_artifact_by_params( - model_version_id=model_version_id - ) - return py_mv def get_model_versions( self, registered_model_id: str, options: ListOptions | None = None - ) -> Sequence[ModelVersion]: + ) -> list[ModelVersion]: """Fetch model versions by registered model ID. Args: @@ -209,16 +205,12 @@ def get_model_versions( """ mlmd_options = options.as_mlmd_list_options() if options else MLMDListOptions() mlmd_options.filter_query = f"parent_contexts_a.id = {registered_model_id}" - proto_mvs = self._store.get_contexts( - ModelVersion.get_proto_type_name(), mlmd_options - ) - py_mvs: list[ModelVersion] = [] - for proto_mv in proto_mvs: - py_mv = ModelVersion.unmap(proto_mv) - assert py_mv.id is not None, "Model version ID is None" - py_mv.model = self.get_model_artifact_by_params(model_version_id=py_mv.id) - py_mvs.append(py_mv) - return py_mvs + return [ + ModelVersion.unmap(proto_mv) + for proto_mv in self._store.get_contexts( + ModelVersion.get_proto_type_name(), mlmd_options + ) + ] def get_model_version_by_params( self, @@ -252,9 +244,7 @@ def get_model_version_by_params( ModelVersion.get_proto_type_name(), name=f"{registered_model_id}:{version}", ) - py_mv = ModelVersion.unmap(proto_mv) - py_mv.model = self.get_model_artifact_by_params(model_version_id=py_mv.id) - return py_mv + return ModelVersion.unmap(proto_mv) def upsert_model_artifact( self, model_artifact: ModelArtifact, model_version_id: str diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 909c283e..b51de06f 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -19,7 +19,7 @@ from model_registry.store import ScalarType -from .artifacts import BaseArtifact, ModelArtifact +from .artifacts import BaseArtifact from .base import Prefixable, ProtoBase @@ -38,7 +38,7 @@ class ModelVersion(BaseContext, Prefixable): """Represents a model version. Attributes: - model: Model associated with this version. + model_name: Name of the model associated with this version. version: Version of the model. author: Author of the model version. description: Description of the object. @@ -48,7 +48,7 @@ class ModelVersion(BaseContext, Prefixable): metadata: Metadata associated with this version. """ - model: ModelArtifact + model_name: str version: str author: str artifacts: list[BaseArtifact] = field(init=False, factory=list) @@ -72,7 +72,7 @@ def mlmd_name_prefix(self): def map(self, type_id: int) -> Context: mlmd_obj = super().map(type_id) # this should match the name of the registered model - mlmd_obj.properties["model_name"].string_value = self.model.name + mlmd_obj.properties["model_name"].string_value = self.model_name mlmd_obj.properties["author"].string_value = self.author if self.tags: mlmd_obj.properties["tags"].string_value = ",".join(self.tags) @@ -87,6 +87,7 @@ def unmap(cls, mlmd_obj: Context) -> ModelVersion: py_obj, ModelVersion ), f"Expected ModelVersion, got {type(py_obj)}" py_obj.version = py_obj.name + py_obj.model_name = mlmd_obj.properties["model_name"].string_value py_obj.author = mlmd_obj.properties["author"].string_value tags = mlmd_obj.properties["tags"].string_value if tags: diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index a43b5408..dbaaf773 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -70,7 +70,7 @@ def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: ctx.properties["author"].string_value = "author" ctx.properties["model_name"].string_value = model.py.name - return Mapped(ctx, ModelVersion(model.py, "version", "author")) + return Mapped(ctx, ModelVersion(model.py.name, "version", "author")) @pytest.fixture() @@ -104,18 +104,10 @@ def test_get_registered_model_by_id( model_registry: ModelRegistry, registered_model: Mapped, model_version: Mapped, - model: Mapped, ): - model.proto.name = f"test_prefix:{model.proto.name}" - ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - model_version.proto.name = f"1:{model_version.proto.name}" mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_registry._store._mlmd_store.put_attributions_and_associations( - [Attribution(context_id=mv_id, artifact_id=ma_id)], [] - ) - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] model_registry._store._mlmd_store.put_parent_contexts( @@ -132,18 +124,10 @@ def test_get_registered_model_by_name( model_registry: ModelRegistry, registered_model: Mapped, model_version: Mapped, - model: Mapped, ): - model.proto.name = f"test_prefix:{model.proto.name}" - ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - model_version.proto.name = f"1:{model_version.proto.name}" mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_registry._store._mlmd_store.put_attributions_and_associations( - [Attribution(context_id=mv_id, artifact_id=ma_id)], [] - ) - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] model_registry._store._mlmd_store.put_parent_contexts( @@ -162,18 +146,10 @@ def test_get_registered_model_by_external_id( model_registry: ModelRegistry, registered_model: Mapped, model_version: Mapped, - model: Mapped, ): - model.proto.name = f"test_prefix:{model.proto.name}" - ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - model_version.proto.name = f"1:{model_version.proto.name}" mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_registry._store._mlmd_store.put_attributions_and_associations( - [Attribution(context_id=mv_id, artifact_id=ma_id)], [] - ) - registered_model.py.external_id = "external_id" registered_model.proto.external_id = "external_id" @@ -217,19 +193,10 @@ def test_upsert_model_version( assert model_version.py.version != mv_proto.name -def test_get_model_version_by_id( - model_registry: ModelRegistry, model: Mapped, model_version: Mapped -): - model.proto.name = f"test_prefix:{model.proto.name}" - art_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - +def test_get_model_version_by_id(model_registry: ModelRegistry, model_version: Mapped): model_version.proto.name = f"1:{model_version.proto.name}" ctx_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_registry._store._mlmd_store.put_attributions_and_associations( - [Attribution(context_id=ctx_id, artifact_id=art_id)], [] - ) - id = str(ctx_id) mlmd_mv = model_registry.get_model_version_by_id(id) assert mlmd_mv.id == id @@ -238,51 +205,31 @@ def test_get_model_version_by_id( def test_get_model_version_by_name( - model_registry: ModelRegistry, model_version: Mapped, model: Mapped + model_registry: ModelRegistry, model_version: Mapped ): - model.proto.name = f"test_prefix:{model.proto.name}" - ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - model_version.proto.name = f"1:{model_version.proto.name}" - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_registry._store._mlmd_store.put_attributions_and_associations( - [Attribution(context_id=mv_id, artifact_id=ma_id)], [] - ) - - id = str(mv_id) - mlmd_mv = model_registry.get_model_version_by_params( registered_model_id="1", version=model_version.py.name ) - assert mlmd_mv.id == id + assert mlmd_mv.id == str(mv_id) assert mlmd_mv.name == model_version.py.name assert mlmd_mv.name != model_version.proto.name def test_get_model_version_by_external_id( - model_registry: ModelRegistry, model_version: Mapped, model: Mapped + model_registry: ModelRegistry, model_version: Mapped ): - model.proto.name = f"test_prefix:{model.proto.name}" - ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - model_version.proto.name = f"1:{model_version.proto.name}" model_version.proto.external_id = "external_id" model_version.py.external_id = "external_id" - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_registry._store._mlmd_store.put_attributions_and_associations( - [Attribution(context_id=mv_id, artifact_id=ma_id)], [] - ) - - id = str(mv_id) - mlmd_mv = model_registry.get_model_version_by_params( external_id=model_version.py.external_id ) - assert mlmd_mv.id == id + assert mlmd_mv.id == str(mv_id) assert mlmd_mv.name == model_version.py.name assert mlmd_mv.name != model_version.proto.name @@ -291,11 +238,7 @@ def test_get_model_versions( model_registry: ModelRegistry, model_version: Mapped, registered_model: Mapped, - model: Mapped, ): - model.proto.name = f"test_prefix:{model.proto.name}" - ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] model_version.proto.name = f"{rm_id}:version" @@ -303,14 +246,6 @@ def test_get_model_versions( model_version.proto.name = f"{rm_id}:version2" mv2_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_registry._store._mlmd_store.put_attributions_and_associations( - [ - Attribution(context_id=mv1_id, artifact_id=ma_id), - Attribution(context_id=mv2_id, artifact_id=ma_id), - ], - [], - ) - model_registry._store._mlmd_store.put_parent_contexts( [ ParentContext(parent_id=rm_id, child_id=mv1_id), diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index 98d8db22..14762a56 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -6,7 +6,7 @@ import pytest from ml_metadata.proto import Context -from model_registry.types import ModelArtifact, ModelVersion +from model_registry.types import ModelVersion from .. import Mapped @@ -26,10 +26,8 @@ def full_model_version() -> Mapped: proto_version.custom_properties["bool_key"].bool_value = True proto_version.custom_properties["str_key"].string_value = "test_str" - py_model = ModelArtifact("test_model", "test_uri") - py_version = ModelVersion( - py_model, + "test_model", "1.0.0", "test_author", external_id="test_external_id", @@ -54,9 +52,7 @@ def minimal_model_version() -> Mapped: proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" - py_model = ModelArtifact("test_model", "test_uri") - - py_version = ModelVersion(py_model, "1.0.0", "test_author") + py_version = ModelVersion("test_model", "1.0.0", "test_author") py_version._registered_model_id = 1 return Mapped(proto_version, py_version) @@ -79,21 +75,23 @@ def test_full_model_version_mapping(full_model_version: Mapped): assert mapped_version.custom_properties == proto_version.custom_properties -def test_full_model_version_unmapping(full_model_version: Mapped): - unmapped_version = ModelVersion.unmap(full_model_version.proto) - py_version = full_model_version.py +def test_partial_model_version_unmapping(minimal_model_version: Mapped): + unmapped_version = ModelVersion.unmap(minimal_model_version.proto) + py_version = minimal_model_version.py assert unmapped_version.version == py_version.version - assert unmapped_version.description == py_version.description - assert unmapped_version.external_id == py_version.external_id + assert unmapped_version.model_name == py_version.model_name assert unmapped_version.author == py_version.author assert unmapped_version.tags == py_version.tags assert unmapped_version.metadata == py_version.metadata -def test_partial_model_version_unmapping(minimal_model_version: Mapped): - unmapped_version = ModelVersion.unmap(minimal_model_version.proto) - py_version = minimal_model_version.py +def test_full_model_version_unmapping(full_model_version: Mapped): + unmapped_version = ModelVersion.unmap(full_model_version.proto) + py_version = full_model_version.py assert unmapped_version.version == py_version.version + assert unmapped_version.description == py_version.description + assert unmapped_version.external_id == py_version.external_id + assert unmapped_version.model_name == py_version.model_name assert unmapped_version.author == py_version.author assert unmapped_version.tags == py_version.tags assert unmapped_version.metadata == py_version.metadata From bf56ee21940d0c302e59f68974d84fb2e3f2ffa1 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 28 Nov 2023 18:17:43 -0300 Subject: [PATCH 170/254] py: get rid of versions on RM Stop managing ModelVersions on RegisteredModel. This also allows us to simplify tests. Closes: #206 Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 3 --- clients/python/src/model_registry/client.py | 13 ++-------- .../src/model_registry/types/contexts.py | 2 -- clients/python/tests/test_client.py | 25 ------------------- 4 files changed, 2 insertions(+), 41 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index ccf7cfb8..9138e18c 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -70,9 +70,6 @@ another_model = registry.get_registered_model_by_id("another-model-id") another_version = registry.get_model_version_by_id("another-version-id", another_model.id) -# fetching a version will also fetch its associated model artifact -model_artifact = another_version.model - another_trained_model = registry.get_model_artifact_by_id("another-model-artifact-id") ``` diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index 41f74e75..e7cb3643 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -92,13 +92,9 @@ def get_registered_model_by_id(self, id: str) -> RegisteredModel: Returns: Registered model. """ - py_rm = RegisteredModel.unmap( + return RegisteredModel.unmap( self._store.get_context(RegisteredModel.get_proto_type_name(), id=int(id)) ) - versions = self.get_model_versions(id) - assert isinstance(versions, list), "Expected a list" - py_rm.versions = versions - return py_rm def get_registered_model_by_params( self, name: str | None = None, external_id: str | None = None @@ -115,18 +111,13 @@ def get_registered_model_by_params( if name is None and external_id is None: msg = "Either name or external_id must be provided" raise StoreException(msg) - py_rm = RegisteredModel.unmap( + return RegisteredModel.unmap( self._store.get_context( RegisteredModel.get_proto_type_name(), name=name, external_id=external_id, ) ) - assert py_rm.id is not None - versions = self.get_model_versions(py_rm.id) - assert isinstance(versions, list), "Expected a list" - py_rm.versions = versions - return py_rm def get_registered_models( self, options: ListOptions | None = None diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index b51de06f..2a8a5d32 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -105,11 +105,9 @@ class RegisteredModel(BaseContext): name: Registered model name. description: Description of the object. external_id: Customizable ID. Has to be unique among instances of the same type. - versions: Versions associated with this model. """ name: str - versions: list[ModelVersion] = field(init=False, factory=list) @classmethod @override diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index dbaaf773..e198d628 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -103,17 +103,9 @@ def test_upsert_registered_model( def test_get_registered_model_by_id( model_registry: ModelRegistry, registered_model: Mapped, - model_version: Mapped, ): - model_version.proto.name = f"1:{model_version.proto.name}" - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - model_registry._store._mlmd_store.put_parent_contexts( - [ParentContext(parent_id=rm_id, child_id=mv_id)] - ) - mlmd_rm = model_registry.get_registered_model_by_id(str(rm_id)) assert mlmd_rm.id == str(rm_id) assert mlmd_rm.name == registered_model.py.name @@ -123,17 +115,9 @@ def test_get_registered_model_by_id( def test_get_registered_model_by_name( model_registry: ModelRegistry, registered_model: Mapped, - model_version: Mapped, ): - model_version.proto.name = f"1:{model_version.proto.name}" - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - model_registry._store._mlmd_store.put_parent_contexts( - [ParentContext(parent_id=rm_id, child_id=mv_id)] - ) - mlmd_rm = model_registry.get_registered_model_by_params( name=registered_model.py.name ) @@ -145,20 +129,11 @@ def test_get_registered_model_by_name( def test_get_registered_model_by_external_id( model_registry: ModelRegistry, registered_model: Mapped, - model_version: Mapped, ): - model_version.proto.name = f"1:{model_version.proto.name}" - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - registered_model.py.external_id = "external_id" registered_model.proto.external_id = "external_id" - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - model_registry._store._mlmd_store.put_parent_contexts( - [ParentContext(parent_id=rm_id, child_id=mv_id)] - ) - mlmd_rm = model_registry.get_registered_model_by_params( external_id=registered_model.py.external_id ) From 0374d63a4a5d1fa08d30a73776d3647de316f830 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 28 Nov 2023 19:48:26 -0300 Subject: [PATCH 171/254] py: return None on missing object We were already doing that implicitly when querying objects by type and name. Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/client.py | 57 ++++++++++++------- .../src/model_registry/store/wrapper.py | 14 ++--- clients/python/tests/store/test_wrapper.py | 6 +- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/client.py index e7cb3643..118451c8 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/client.py @@ -83,7 +83,7 @@ def upsert_registered_model(self, registered_model: RegisteredModel) -> str: ) return id - def get_registered_model_by_id(self, id: str) -> RegisteredModel: + def get_registered_model_by_id(self, id: str) -> RegisteredModel | None: """Fetch a registered model by its ID. Args: @@ -92,13 +92,17 @@ def get_registered_model_by_id(self, id: str) -> RegisteredModel: Returns: Registered model. """ - return RegisteredModel.unmap( - self._store.get_context(RegisteredModel.get_proto_type_name(), id=int(id)) + proto_rm = self._store.get_context( + RegisteredModel.get_proto_type_name(), id=int(id) ) + if proto_rm is not None: + return RegisteredModel.unmap(proto_rm) + + return None def get_registered_model_by_params( self, name: str | None = None, external_id: str | None = None - ) -> RegisteredModel: + ) -> RegisteredModel | None: """Fetch a registered model by its name or external ID. Args: @@ -111,13 +115,15 @@ def get_registered_model_by_params( if name is None and external_id is None: msg = "Either name or external_id must be provided" raise StoreException(msg) - return RegisteredModel.unmap( - self._store.get_context( - RegisteredModel.get_proto_type_name(), - name=name, - external_id=external_id, - ) + proto_rm = self._store.get_context( + RegisteredModel.get_proto_type_name(), + name=name, + external_id=external_id, ) + if proto_rm is not None: + return RegisteredModel.unmap(proto_rm) + + return None def get_registered_models( self, options: ListOptions | None = None @@ -176,11 +182,13 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: Returns: Model version. """ - return ModelVersion.unmap( - self._store.get_context( - ModelVersion.get_proto_type_name(), id=int(model_version_id) - ) + proto_mv = self._store.get_context( + ModelVersion.get_proto_type_name(), id=int(model_version_id) ) + if proto_mv is not None: + return ModelVersion.unmap(proto_mv) + + return None def get_model_versions( self, registered_model_id: str, options: ListOptions | None = None @@ -208,7 +216,7 @@ def get_model_version_by_params( registered_model_id: str | None = None, version: str | None = None, external_id: str | None = None, - ) -> ModelVersion: + ) -> ModelVersion | None: """Fetch a model version by associated parameters. Either fetches by using external ID or by using registered model ID and version. @@ -235,7 +243,10 @@ def get_model_version_by_params( ModelVersion.get_proto_type_name(), name=f"{registered_model_id}:{version}", ) - return ModelVersion.unmap(proto_mv) + if proto_mv is not None: + return ModelVersion.unmap(proto_mv) + + return None def upsert_model_artifact( self, model_artifact: ModelArtifact, model_version_id: str @@ -276,7 +287,7 @@ def upsert_model_artifact( ) return id - def get_model_artifact_by_id(self, id: str) -> ModelArtifact: + def get_model_artifact_by_id(self, id: str) -> ModelArtifact | None: """Fetch a model artifact by its ID. Args: @@ -288,11 +299,14 @@ def get_model_artifact_by_id(self, id: str) -> ModelArtifact: proto_ma = self._store.get_artifact( ModelArtifact.get_proto_type_name(), int(id) ) - return ModelArtifact.unmap(proto_ma) + if proto_ma is not None: + return ModelArtifact.unmap(proto_ma) + + return None def get_model_artifact_by_params( self, model_version_id: str | None = None, external_id: str | None = None - ) -> ModelArtifact: + ) -> ModelArtifact | None: """Fetch a model artifact either by external ID or by the ID of its associated model version. Args: @@ -313,7 +327,10 @@ def get_model_artifact_by_params( proto_ma = self._store.get_attributed_artifact( ModelArtifact.get_proto_type_name(), int(model_version_id) ) - return ModelArtifact.unmap(proto_ma) + if proto_ma is not None: + return ModelArtifact.unmap(proto_ma) + + return None def get_model_artifacts( self, diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index e007b8e7..50056d80 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -144,7 +144,7 @@ def get_context( id: int | None = None, name: str | None = None, external_id: str | None = None, - ) -> Context: + ) -> Context | None: """Get a context from the store. This gets a context either by ID, name or external ID. @@ -160,7 +160,7 @@ def get_context( Context. Raises: - StoreException: If the context doesn't exist. + StoreException: Invalid arguments. """ if name is not None: return self._mlmd_store.get_context_by_type_and_name(ctx_type_name, name) @@ -177,8 +177,7 @@ def get_context( if contexts: return contexts[0] - msg = f"Context with ID {id} does not exist" - raise StoreException(msg) + return None def get_contexts( self, ctx_type_name: str, options: ListOptions @@ -266,7 +265,7 @@ def get_artifact( id: int | None = None, name: str | None = None, external_id: str | None = None, - ) -> Artifact: + ) -> Artifact | None: """Get an artifact from the store. Gets an artifact either by ID, name or external ID. @@ -281,7 +280,7 @@ def get_artifact( Artifact. Raises: - StoreException: If the context doesn't exist. + StoreException: Invalid arguments. """ if name is not None: return self._mlmd_store.get_artifact_by_type_and_name(art_type_name, name) @@ -298,8 +297,7 @@ def get_artifact( if artifacts: return artifacts[0] - msg = f"Artifact with ID {id} does not exist" - raise StoreException(msg) + return None def get_attributed_artifact(self, art_type_name: str, ctx_id: int) -> Artifact: """Get an artifact from the store by its attributed context. diff --git a/clients/python/tests/store/test_wrapper.py b/clients/python/tests/store/test_wrapper.py index d5fcd5f7..ae699693 100644 --- a/clients/python/tests/store/test_wrapper.py +++ b/clients/python/tests/store/test_wrapper.py @@ -103,10 +103,8 @@ def test_put_attribution_with_invalid_artifact( def test_get_undefined_artifact_by_id(store_wrapper: MLMDStore): - with pytest.raises(StoreException): - store_wrapper.get_artifact("dup", 0) + assert store_wrapper.get_artifact("dup", 0) is None def test_get_undefined_context_by_id(store_wrapper: MLMDStore): - with pytest.raises(StoreException): - store_wrapper.get_context("dup", 0) + assert store_wrapper.get_context("dup", 0) is None From 7dce2a9f6024af408fbfc1285138717651330ad3 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 28 Nov 2023 19:48:28 -0300 Subject: [PATCH 172/254] py: tests: extract populated store wrapper Signed-off-by: Isabella Basso do Amaral --- clients/python/tests/conftest.py | 64 +++++++++++++++++++++- clients/python/tests/store/test_wrapper.py | 56 +++++++++---------- clients/python/tests/test_client.py | 41 +++----------- 3 files changed, 97 insertions(+), 64 deletions(-) diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py index c92ac722..c4749c15 100644 --- a/clients/python/tests/conftest.py +++ b/clients/python/tests/conftest.py @@ -1,10 +1,70 @@ +from typing import Union + import pytest -from ml_metadata.proto import ConnectionConfig +from ml_metadata.proto import ( + ArtifactType, + ConnectionConfig, + ContextType, + metadata_store_pb2, +) from model_registry.store.wrapper import MLMDStore +from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel @pytest.fixture() -def store_wrapper() -> MLMDStore: +def plain_wrapper() -> MLMDStore: config = ConnectionConfig() config.fake_database.SetInParent() return MLMDStore(config) + + +def set_type_attrs( + mlmd_obj: Union[ArtifactType, ContextType], name: str, props: list[str] +): + mlmd_obj.name = name + for key in props: + mlmd_obj.properties[key] = metadata_store_pb2.STRING + return mlmd_obj + + +@pytest.fixture() +def store_wrapper(plain_wrapper: MLMDStore) -> MLMDStore: + ma_type = set_type_attrs( + ArtifactType(), + ModelArtifact.get_proto_type_name(), + [ + "description", + "model_format_name", + "model_format_version", + "storage_key", + "storage_path", + "service_account_name", + ], + ) + + plain_wrapper._mlmd_store.put_artifact_type(ma_type) + + mv_type = set_type_attrs( + ContextType(), + ModelVersion.get_proto_type_name(), + [ + "author", + "description", + "model_name", + "tags", + ], + ) + + plain_wrapper._mlmd_store.put_context_type(mv_type) + + rm_type = set_type_attrs( + ContextType(), + RegisteredModel.get_proto_type_name(), + [ + "description", + ], + ) + + plain_wrapper._mlmd_store.put_context_type(rm_type) + + return plain_wrapper diff --git a/clients/python/tests/store/test_wrapper.py b/clients/python/tests/store/test_wrapper.py index ae699693..c2d379de 100644 --- a/clients/python/tests/store/test_wrapper.py +++ b/clients/python/tests/store/test_wrapper.py @@ -20,91 +20,91 @@ @pytest.fixture() -def artifact(store_wrapper: MLMDStore) -> Artifact: +def artifact(plain_wrapper: MLMDStore) -> Artifact: art_type = ArtifactType() art_type.name = "test_artifact" art = Artifact() art.name = "test_artifact" - art.type_id = store_wrapper._mlmd_store.put_artifact_type(art_type) + art.type_id = plain_wrapper._mlmd_store.put_artifact_type(art_type) return art @pytest.fixture() -def context(store_wrapper: MLMDStore) -> Context: +def context(plain_wrapper: MLMDStore) -> Context: ctx_type = ContextType() ctx_type.name = "test_context" ctx = Context() ctx.name = "test_context" - ctx.type_id = store_wrapper._mlmd_store.put_context_type(ctx_type) + ctx.type_id = plain_wrapper._mlmd_store.put_context_type(ctx_type) return ctx -def test_get_undefined_artifact_type_id(store_wrapper: MLMDStore): +def test_get_undefined_artifact_type_id(plain_wrapper: MLMDStore): with pytest.raises(TypeNotFoundException): - store_wrapper.get_type_id(Artifact, "undefined") + plain_wrapper.get_type_id(Artifact, "undefined") -def test_get_undefined_context_type_id(store_wrapper: MLMDStore): +def test_get_undefined_context_type_id(plain_wrapper: MLMDStore): with pytest.raises(TypeNotFoundException): - store_wrapper.get_type_id(Context, "undefined") + plain_wrapper.get_type_id(Context, "undefined") -def test_put_invalid_artifact(store_wrapper: MLMDStore, artifact: Artifact): +def test_put_invalid_artifact(plain_wrapper: MLMDStore, artifact: Artifact): artifact.properties["null"].int_value = 0 with pytest.raises(StoreException): - store_wrapper.put_artifact(artifact) + plain_wrapper.put_artifact(artifact) -def test_put_duplicate_artifact(store_wrapper: MLMDStore, artifact: Artifact): - store_wrapper._mlmd_store.put_artifacts([artifact]) +def test_put_duplicate_artifact(plain_wrapper: MLMDStore, artifact: Artifact): + plain_wrapper._mlmd_store.put_artifacts([artifact]) with pytest.raises(DuplicateException): - store_wrapper.put_artifact(artifact) + plain_wrapper.put_artifact(artifact) -def test_put_invalid_context(store_wrapper: MLMDStore, context: Context): +def test_put_invalid_context(plain_wrapper: MLMDStore, context: Context): context.properties["null"].int_value = 0 with pytest.raises(StoreException): - store_wrapper.put_context(context) + plain_wrapper.put_context(context) -def test_put_duplicate_context(store_wrapper: MLMDStore, context: Context): - store_wrapper._mlmd_store.put_contexts([context]) +def test_put_duplicate_context(plain_wrapper: MLMDStore, context: Context): + plain_wrapper._mlmd_store.put_contexts([context]) with pytest.raises(DuplicateException): - store_wrapper.put_context(context) + plain_wrapper.put_context(context) def test_put_attribution_with_invalid_context( - store_wrapper: MLMDStore, artifact: Artifact + plain_wrapper: MLMDStore, artifact: Artifact ): - art_id = store_wrapper._mlmd_store.put_artifacts([artifact])[0] + art_id = plain_wrapper._mlmd_store.put_artifacts([artifact])[0] with pytest.raises(StoreException) as store_error: - store_wrapper.put_attribution(0, art_id) + plain_wrapper.put_attribution(0, art_id) assert "context" in str(store_error.value).lower() def test_put_attribution_with_invalid_artifact( - store_wrapper: MLMDStore, context: Context + plain_wrapper: MLMDStore, context: Context ): - ctx_id = store_wrapper._mlmd_store.put_contexts([context])[0] + ctx_id = plain_wrapper._mlmd_store.put_contexts([context])[0] with pytest.raises(StoreException) as store_error: - store_wrapper.put_attribution(ctx_id, 0) + plain_wrapper.put_attribution(ctx_id, 0) assert "artifact" in str(store_error.value).lower() -def test_get_undefined_artifact_by_id(store_wrapper: MLMDStore): - assert store_wrapper.get_artifact("dup", 0) is None +def test_get_undefined_artifact_by_id(plain_wrapper: MLMDStore): + assert plain_wrapper.get_artifact("dup", 0) is None -def test_get_undefined_context_by_id(store_wrapper: MLMDStore): - assert store_wrapper.get_context("dup", 0) is None +def test_get_undefined_context_by_id(plain_wrapper: MLMDStore): + assert plain_wrapper.get_context("dup", 0) is None diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index e198d628..d334bd6c 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -4,12 +4,9 @@ from attrs import evolve from ml_metadata.proto import ( Artifact, - ArtifactType, Attribution, Context, - ContextType, ParentContext, - metadata_store_pb2, ) from model_registry import ModelRegistry from model_registry.exceptions import StoreException @@ -28,23 +25,12 @@ def model_registry(store_wrapper: MLMDStore) -> ModelRegistry: @pytest.fixture() def model(store_wrapper: MLMDStore) -> Mapped: - art_type = ArtifactType() - art_type.name = ModelArtifact.get_proto_type_name() - props = [ - "description", - "model_format_name", - "model_format_version", - "storage_key", - "storage_path", - "service_account_name", - ] - for key in props: - art_type.properties[key] = metadata_store_pb2.STRING - art = Artifact() # we can't test the name directly as it's prefixed art.name = "model" - art.type_id = store_wrapper._mlmd_store.put_artifact_type(art_type) + art.type_id = store_wrapper.get_type_id( + Artifact, ModelArtifact.get_proto_type_name() + ) art.uri = "uri" return Mapped(art, ModelArtifact("model", "uri")) @@ -52,21 +38,10 @@ def model(store_wrapper: MLMDStore) -> Mapped: @pytest.fixture() def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: - ctx_type = ContextType() - ctx_type.name = ModelVersion.get_proto_type_name() - props = [ - "author", - "description", - "model_name", - "tags", - ] - for key in props: - ctx_type.properties[key] = metadata_store_pb2.STRING - ctx = Context() # we can't test the name directly as it's prefixed ctx.name = "version" - ctx.type_id = store_wrapper._mlmd_store.put_context_type(ctx_type) + ctx.type_id = store_wrapper.get_type_id(Context, ModelVersion.get_proto_type_name()) ctx.properties["author"].string_value = "author" ctx.properties["model_name"].string_value = model.py.name @@ -75,13 +50,11 @@ def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: @pytest.fixture() def registered_model(store_wrapper: MLMDStore, model: Mapped) -> Mapped: - ctx_type = ContextType() - ctx_type.name = RegisteredModel.get_proto_type_name() - ctx_type.properties["description"] = metadata_store_pb2.STRING - ctx = Context() ctx.name = model.py.name - ctx.type_id = store_wrapper._mlmd_store.put_context_type(ctx_type) + ctx.type_id = store_wrapper.get_type_id( + Context, RegisteredModel.get_proto_type_name() + ) return Mapped(ctx, RegisteredModel(model.py.name)) From 2ae6e46959135b76089651c91a0db18577ecd029 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 28 Nov 2023 19:48:29 -0300 Subject: [PATCH 173/254] py: add higher-level API The low-level client gets moved to core. Previous docs get moved into reference. The client submodule is underscored to make it "private", thus only letting the user import it from the MR module directly, i.e. ```py from model_registry import ModelRegistry # but now # from model_registry.client import ModelRegistry ``` Core tests are moved into a separate file, while the previous `test_client` file now has tests for the new frontend behavior. Related: #129 Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 145 +------ clients/python/docs/reference.md | 140 ++++++- clients/python/src/model_registry/__init__.py | 5 +- clients/python/src/model_registry/_client.py | 148 +++++++ .../src/model_registry/{client.py => core.py} | 4 +- .../src/model_registry/types/__init__.py | 5 +- clients/python/tests/conftest.py | 14 +- clients/python/tests/test_client.py | 368 ++---------------- clients/python/tests/test_core.py | 344 ++++++++++++++++ 9 files changed, 705 insertions(+), 468 deletions(-) create mode 100644 clients/python/src/model_registry/_client.py rename clients/python/src/model_registry/{client.py => core.py} (99%) create mode 100644 clients/python/tests/test_core.py diff --git a/clients/python/README.md b/clients/python/README.md index 9138e18c..93575223 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -3,148 +3,29 @@ [![Python](https://img.shields.io/badge/python%20-3.9%7C3.10-blue)](https://github.com/opendatahub-io/model-registry) [![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](../../../LICENSE) -This library provides a low level interface for interacting with a model registry server. - -Types are based on [ML Metadata](https://github.com/google/ml-metadata), with Pythonic class wrappers. +This library provides a high level interface for interacting with a model registry server. ## Basic usage -### Create objects - -Registry objects can be created by doing - - - - -```py -from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel - -trained_model = ModelArtifact("my_model_name", "resource_URI", - description="Model description") - -version = ModelVersion(trained_model, "v1.0", "model author") - -model = RegisteredModel("my_model_name") -``` - -### Register objects - - -To register those objects, you can use the [`model_registry.ModelRegistry` class](src/model_registry/registry/client.py): - ```py from model_registry import ModelRegistry -registry = ModelRegistry("server-address", "port") - -model_id = registry.upsert_registered_model(model) - -# we need a model to associate the version to -version_id = registry.upsert_model_version(version, model_id) - -# we need a version to associate an trained model to -experiment_id = registry.upsert_model_artifact(trained_model, version_id) -``` - -### Query objects - -There are several ways to get previously registered objects from the registry. - -#### By ID - -IDs are created once the object is registered, you can either keep the string returned by the -`upsert_*` functions, or access the `id` property of the objects. - -```py -new_model = RegisteredModel("new_model") - -new_model_id = registry.upsert_registered_model(new_model) - -assert new_model_id == new_model.id -``` - -To query objects using IDs, do - -```py -another_model = registry.get_registered_model_by_id("another-model-id") - -another_version = registry.get_model_version_by_id("another-version-id", another_model.id) - -another_trained_model = registry.get_model_artifact_by_id("another-model-artifact-id") -``` - -#### By parameters - - -External IDs can be used to query objects in the wild. -Note that external IDs must be unique among [artifacts](src/model_registry/types/artifacts.py) or -[contexts](src/model_registry/types/contexts.py). - -```py -trained_model = ModelArtifact("my_model_name", "resource_URI", - description="Model description", - external_id="unique_reference") - -# As a version is a context, we can have the same external_id as the above -version = ModelVersion(trained_model, "v1.0", "model author", - external_id="unique_reference") - -# Registering this will cause an error! -# model = RegisteredModel("my_model_name", -# external_id="unique_reference") - -model = RegisteredModel("my_model_name", - external_id="another_unique_reference") -``` - -You can also perform queries by parameters: - -```py -# We can get the model artifact associated to a version -another_trained_model = registry.get_model_artifact_by_params(model_version_id=another_version.id) - -# Or by its unique identifier -trained_model = registry.get_model_artifact_by_params(external_id="unique_reference") - -# Same thing for a version -version = registry.get_model_version_by_params(external_id="unique_reference") - -# Or for a model -model = registry.get_registered_model_by_params(external_id="another_unique_reference") - -# We can also get a version by its name and associated model id -version = registry.get_model_version_by_params(version="v1.0", registered_model_id="x") - -# And we can get a model by simply calling its name -model = registry.get_registered_model_by_params(name="my_model_name") -``` - -### Query multiple objects - -We can query all objects of a type - -```py -models = registry.get_registered_models() - -versions = registry.get_model_versions("registered_model_id") - -# We can get a list of all model artifacts -all_model_artifacts = registry.get_model_artifacts() -``` - -To limit or order the query, provide a [`ListOptions`](src/model_registry/types/options.py) object - -```py -from model_registry import ListOptions, OrderByField +registry = ModelRegistry(address="server-address", port="port", author="author") -options = ListOptions(limit=50) +model = registry.register_model("my-model", + "s3://path/to/model", + format_name="onnx", + format_version="v1", + secret_account_name="access", + version="v2.0", + description="lorem ipsum", + ) -first_50_models = registry.get_registered_models(options) +model = registry.get_registered_model("my-model") -# By default we get ascending order -options = ListOptions(order_by=OrderByField.CREATE_TIME, is_asc=False) +version = registry.get_model_version("my-model", "v2.0") -last_50_models = registry.get_registered_models(options) +experiment = registry.get_model_artifact("my-model", "v2.0") ``` ## Development diff --git a/clients/python/docs/reference.md b/clients/python/docs/reference.md index 9e39ca75..f8fb44c5 100644 --- a/clients/python/docs/reference.md +++ b/clients/python/docs/reference.md @@ -3,11 +3,149 @@ ## Client ```{eval-rst} -.. automodule:: model_registry.client +.. automodule:: model_registry +``` + +## Core + +### Register objects + +```py +from model_registry import ModelRegistry + +registry = ModelRegistry("server-address", "port") + +model_id = registry.upsert_registered_model(model) + +# we need a model to associate the version to +version_id = registry.upsert_model_version(version, model_id) + +# we need a version to associate an trained model to +experiment_id = registry.upsert_model_artifact(trained_model, version_id) +``` + +### Query objects + +There are several ways to get previously registered objects from the registry. + +#### By ID + +IDs are created once the object is registered, you can either keep the string returned by the +`upsert_*` functions, or access the `id` property of the objects. + +```py +new_model = RegisteredModel("new_model") + +new_model_id = registry.upsert_registered_model(new_model) + +assert new_model_id == new_model.id +``` + +To query objects using IDs, do + +```py +another_model = registry.get_registered_model_by_id("another-model-id") + +another_version = registry.get_model_version_by_id("another-version-id", another_model.id) + +another_trained_model = registry.get_model_artifact_by_id("another-model-artifact-id") +``` + +#### By parameters + +External IDs can be used to query objects in the wild. +Note that external IDs must be unique among artifacts or +contexts (see [Types](#types)). + +```py +trained_model = ModelArtifact("my_model_name", "resource_URI", + description="Model description", + external_id="unique_reference") + +# As a version is a context, we can have the same external_id as the above +version = ModelVersion(trained_model, "v1.0", "model author", + external_id="unique_reference") + +# Registering this will cause an error! +# model = RegisteredModel("my_model_name", +# external_id="unique_reference") + +model = RegisteredModel("my_model_name", + external_id="another_unique_reference") +``` + +You can also perform queries by parameters: + +```py +# We can get the model artifact associated to a version +another_trained_model = registry.get_model_artifact_by_params(model_version_id=another_version.id) + +# Or by its unique identifier +trained_model = registry.get_model_artifact_by_params(external_id="unique_reference") + +# Same thing for a version +version = registry.get_model_version_by_params(external_id="unique_reference") + +# Or for a model +model = registry.get_registered_model_by_params(external_id="another_unique_reference") + +# We can also get a version by its name and associated model id +version = registry.get_model_version_by_params(version="v1.0", registered_model_id="x") + +# And we can get a model by simply calling its name +model = registry.get_registered_model_by_params(name="my_model_name") +``` + +### Query multiple objects + +We can query all objects of a type + +```py +models = registry.get_registered_models() + +versions = registry.get_model_versions("registered_model_id") + +# We can get a list of all model artifacts +all_model_artifacts = registry.get_model_artifacts() +``` + + +To limit or order the query, provide a `ListOptions` object + +```py +from model_registry import ListOptions, OrderByField + +options = ListOptions(limit=50) + +first_50_models = registry.get_registered_models(options) + +# By default we get ascending order +options = ListOptions(order_by=OrderByField.CREATE_TIME, is_asc=False) + +last_50_models = registry.get_registered_models(options) +``` + +```{eval-rst} +.. automodule:: model_registry.core ``` ## Types +### Create objects + +Registry objects can be created by doing + +```py +from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel + +trained_model = ModelArtifact("my_model_name", "resource_URI", + description="Model description") + +version = ModelVersion(trained_model.name, "v1.0", "model author") + +model = RegisteredModel(trained_model.name) +``` + ```{eval-rst} .. automodule:: model_registry.types ``` diff --git a/clients/python/src/model_registry/__init__.py b/clients/python/src/model_registry/__init__.py index 3801c1ad..b9972878 100644 --- a/clients/python/src/model_registry/__init__.py +++ b/clients/python/src/model_registry/__init__.py @@ -2,11 +2,8 @@ __version__ = "0.1.0" -from .client import ModelRegistry -from .types import ListOptions, OrderByField +from ._client import ModelRegistry __all__ = [ "ModelRegistry", - "ListOptions", - "OrderByField", ] diff --git a/clients/python/src/model_registry/_client.py b/clients/python/src/model_registry/_client.py new file mode 100644 index 00000000..4376deaa --- /dev/null +++ b/clients/python/src/model_registry/_client.py @@ -0,0 +1,148 @@ +"""Standard client for the model registry.""" +from __future__ import annotations + +from .core import ModelRegistryAPIClient +from .exceptions import StoreException +from .types import ModelArtifact, ModelVersion, RegisteredModel + + +class ModelRegistry: + """Model registry client.""" + + def __init__( + self, + server_address: str, + port: int, + author: str, + client_key: str | None = None, + server_cert: str | None = None, + custom_ca: str | None = None, + ): + """Constructor. + + Args: + server_address (str): Server address. + port (int): Server port. + author (str): Name of the author. + client_key (str, optional): The PEM-encoded private key as a byte string. + server_cert (str, optional): The PEM-encoded certificate as a byte string. + custom_ca (str, optional): The PEM-encoded root certificates as a byte string. + """ + # TODO: get args from env + self._author = author + self._api = ModelRegistryAPIClient( + server_address, port, client_key, server_cert, custom_ca + ) + + def _register_model(self, name: str) -> RegisteredModel: + if rm := self._api.get_registered_model_by_params(name): + return rm + + rm = RegisteredModel(name) + self._api.upsert_registered_model(rm) + return rm + + def _register_new_version( + self, rm: RegisteredModel, version: str, /, description: str | None + ) -> ModelVersion: + assert rm.id is not None, "Registered model must have an ID" + if self._api.get_model_version_by_params(rm.id, version): + msg = f"Version {version} already exists" + raise StoreException(msg) + + mv = ModelVersion(rm.name, version, self._author, description=description) + self._api.upsert_model_version(mv, rm.id) + return mv + + def _register_model_artifact( + self, mv: ModelVersion, uri: str, /, **kwargs + ) -> ModelArtifact: + assert mv.id is not None, "Model version must have an ID" + ma = ModelArtifact(mv.model_name, uri, **kwargs) + self._api.upsert_model_artifact(ma, mv.id) + return ma + + def register_model( + self, + name: str, + uri: str, + *, + model_format_name: str, + model_format_version: str, + version: str, + description: str | None = None, + storage_key: str | None = None, + storage_path: str | None = None, + service_account_name: str | None = None, + ) -> RegisteredModel: + """Register a model. + + Version has to be unique for the model. + Either `storage_key` and `storage_path`, or `service_account_name` must be provided. + + Args: + name (str): Name of the model. + uri (str): URI of the model. + + Keyword Args: + model_format_name (str): Name of the model format. + model_format_version (str): Version of the model format. + version (str): Version of the model. + description (str, optional): Description of the model. + storage_key (str, optional): Storage key. + storage_path (str, optional): Storage path. + service_account_name (str, optional): Service account name. + + Returns: + RegisteredModel: Registered model. + """ + rm = self._register_model(name) + mv = self._register_new_version(rm, version, description=description) + self._register_model_artifact( + mv, + uri, + model_format_name=model_format_name, + model_format_version=model_format_version, + storage_key=storage_key, + storage_path=storage_path, + service_account_name=service_account_name, + ) + + return rm + + def get_registered_model(self, name: str) -> RegisteredModel: + """Get a registered model. + + Args: + name (str): Name of the model. + + Returns: + RegisteredModel: Registered model. + """ + return self._api.get_registered_model_by_params(name) + + def get_model_version(self, name: str, version: str) -> ModelVersion: + """Get a model version. + + Args: + name (str): Name of the model. + version (str): Version of the model. + + Returns: + ModelVersion: Model version. + """ + rm = self._api.get_registered_model_by_params(name) + return self._api.get_model_version_by_params(rm.id, version) + + def get_model_artifact(self, name: str, version: str) -> ModelArtifact: + """Get a model artifact. + + Args: + name (str): Name of the model. + version (str): Version of the model. + + Returns: + ModelArtifact: Model artifact. + """ + mv = self.get_model_version(name, version) + return self._api.get_model_artifact_by_params(mv.id) diff --git a/clients/python/src/model_registry/client.py b/clients/python/src/model_registry/core.py similarity index 99% rename from clients/python/src/model_registry/client.py rename to clients/python/src/model_registry/core.py index 118451c8..66c04829 100644 --- a/clients/python/src/model_registry/client.py +++ b/clients/python/src/model_registry/core.py @@ -12,8 +12,8 @@ from .types.options import MLMDListOptions -class ModelRegistry: - """Model registry client.""" +class ModelRegistryAPIClient: + """Model registry API.""" def __init__( self, diff --git a/clients/python/src/model_registry/types/__init__.py b/clients/python/src/model_registry/types/__init__.py index df61a02c..8f3e3cde 100644 --- a/clients/python/src/model_registry/types/__init__.py +++ b/clients/python/src/model_registry/types/__init__.py @@ -1,4 +1,7 @@ -"""Model registry types.""" +"""Model registry types. + +Types are based on [ML Metadata](https://github.com/google/ml-metadata), with Pythonic class wrappers. +""" from .artifacts import ArtifactState, ModelArtifact from .contexts import ModelVersion, RegisteredModel diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py index c4749c15..24add635 100644 --- a/clients/python/tests/conftest.py +++ b/clients/python/tests/conftest.py @@ -7,9 +7,12 @@ ContextType, metadata_store_pb2, ) +from model_registry.core import ModelRegistryAPIClient from model_registry.store.wrapper import MLMDStore from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel +ProtoTypeType = Union[ArtifactType, ContextType] + @pytest.fixture() def plain_wrapper() -> MLMDStore: @@ -18,9 +21,7 @@ def plain_wrapper() -> MLMDStore: return MLMDStore(config) -def set_type_attrs( - mlmd_obj: Union[ArtifactType, ContextType], name: str, props: list[str] -): +def set_type_attrs(mlmd_obj: ProtoTypeType, name: str, props: list[str]): mlmd_obj.name = name for key in props: mlmd_obj.properties[key] = metadata_store_pb2.STRING @@ -68,3 +69,10 @@ def store_wrapper(plain_wrapper: MLMDStore) -> MLMDStore: plain_wrapper._mlmd_store.put_context_type(rm_type) return plain_wrapper + + +@pytest.fixture() +def mr_api(store_wrapper: MLMDStore) -> ModelRegistryAPIClient: + mr = object.__new__(ModelRegistryAPIClient) + mr._store = store_wrapper + return mr diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index d334bd6c..1f5f5dfb 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -1,347 +1,65 @@ -"""Tests for user facing model registry APIs.""" - import pytest -from attrs import evolve -from ml_metadata.proto import ( - Artifact, - Attribution, - Context, - ParentContext, -) from model_registry import ModelRegistry +from model_registry.core import ModelRegistryAPIClient from model_registry.exceptions import StoreException -from model_registry.store import MLMDStore -from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel - -from . import Mapped @pytest.fixture() -def model_registry(store_wrapper: MLMDStore) -> ModelRegistry: - mr = object.__new__(ModelRegistry) - mr._store = store_wrapper +def mr_client(mr_api: ModelRegistryAPIClient) -> ModelRegistry: + mr = ModelRegistry.__new__(ModelRegistry) + mr._api = mr_api + mr._author = "test_author" return mr -@pytest.fixture() -def model(store_wrapper: MLMDStore) -> Mapped: - art = Artifact() - # we can't test the name directly as it's prefixed - art.name = "model" - art.type_id = store_wrapper.get_type_id( - Artifact, ModelArtifact.get_proto_type_name() - ) - art.uri = "uri" - - return Mapped(art, ModelArtifact("model", "uri")) - - -@pytest.fixture() -def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: - ctx = Context() - # we can't test the name directly as it's prefixed - ctx.name = "version" - ctx.type_id = store_wrapper.get_type_id(Context, ModelVersion.get_proto_type_name()) - ctx.properties["author"].string_value = "author" - ctx.properties["model_name"].string_value = model.py.name - - return Mapped(ctx, ModelVersion(model.py.name, "version", "author")) - - -@pytest.fixture() -def registered_model(store_wrapper: MLMDStore, model: Mapped) -> Mapped: - ctx = Context() - ctx.name = model.py.name - ctx.type_id = store_wrapper.get_type_id( - Context, RegisteredModel.get_proto_type_name() - ) - - return Mapped(ctx, RegisteredModel(model.py.name)) - - -# TODO: should we test insert/update separately? -def test_upsert_registered_model( - model_registry: ModelRegistry, registered_model: Mapped -): - model_registry.upsert_registered_model(registered_model.py) - - rm_proto = model_registry._store._mlmd_store.get_context_by_type_and_name( - RegisteredModel.get_proto_type_name(), registered_model.proto.name - ) - assert rm_proto is not None - assert registered_model.py.id == str(rm_proto.id) - assert registered_model.py.name == rm_proto.name - - -def test_get_registered_model_by_id( - model_registry: ModelRegistry, - registered_model: Mapped, -): - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - - mlmd_rm = model_registry.get_registered_model_by_id(str(rm_id)) - assert mlmd_rm.id == str(rm_id) - assert mlmd_rm.name == registered_model.py.name - assert mlmd_rm.name == registered_model.proto.name - - -def test_get_registered_model_by_name( - model_registry: ModelRegistry, - registered_model: Mapped, -): - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - - mlmd_rm = model_registry.get_registered_model_by_params( - name=registered_model.py.name - ) - assert mlmd_rm.id == str(rm_id) - assert mlmd_rm.name == registered_model.py.name - assert mlmd_rm.name == registered_model.proto.name - - -def test_get_registered_model_by_external_id( - model_registry: ModelRegistry, - registered_model: Mapped, -): - registered_model.py.external_id = "external_id" - registered_model.proto.external_id = "external_id" - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - - mlmd_rm = model_registry.get_registered_model_by_params( - external_id=registered_model.py.external_id - ) - assert mlmd_rm.id == str(rm_id) - assert mlmd_rm.name == registered_model.py.name - assert mlmd_rm.name == registered_model.proto.name - - -def test_get_registered_models(model_registry: ModelRegistry, registered_model: Mapped): - rm1_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - registered_model.proto.name = "model2" - rm2_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - - mlmd_rms = model_registry.get_registered_models() - assert len(mlmd_rms) == 2 - assert mlmd_rms[0].id in [str(rm1_id), str(rm2_id)] - - -def test_upsert_model_version( - model_registry: ModelRegistry, model_version: Mapped, registered_model: Mapped -): - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - rm_id = str(rm_id) - - model_registry.upsert_model_version(model_version.py, rm_id) - - mv_proto = model_registry._store._mlmd_store.get_context_by_type_and_name( - ModelVersion.get_proto_type_name(), f"{rm_id}:{model_version.proto.name}" - ) - assert mv_proto is not None - assert model_version.py.id == str(mv_proto.id) - assert model_version.py.version != mv_proto.name - - -def test_get_model_version_by_id(model_registry: ModelRegistry, model_version: Mapped): - model_version.proto.name = f"1:{model_version.proto.name}" - ctx_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - - id = str(ctx_id) - mlmd_mv = model_registry.get_model_version_by_id(id) - assert mlmd_mv.id == id - assert mlmd_mv.name == model_version.py.name - assert mlmd_mv.version != model_version.proto.name - - -def test_get_model_version_by_name( - model_registry: ModelRegistry, model_version: Mapped -): - model_version.proto.name = f"1:{model_version.proto.name}" - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - - mlmd_mv = model_registry.get_model_version_by_params( - registered_model_id="1", version=model_version.py.name - ) - assert mlmd_mv.id == str(mv_id) - assert mlmd_mv.name == model_version.py.name - assert mlmd_mv.name != model_version.proto.name - - -def test_get_model_version_by_external_id( - model_registry: ModelRegistry, model_version: Mapped -): - model_version.proto.name = f"1:{model_version.proto.name}" - model_version.proto.external_id = "external_id" - model_version.py.external_id = "external_id" - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - - mlmd_mv = model_registry.get_model_version_by_params( - external_id=model_version.py.external_id +def test_register_new(mr_client: ModelRegistry): + name = "test_model" + version = "1.0.0" + rm = mr_client.register_model( + name, + "s3", + model_format_name="test_format", + model_format_version="test_version", + version=version, ) - assert mlmd_mv.id == str(mv_id) - assert mlmd_mv.name == model_version.py.name - assert mlmd_mv.name != model_version.proto.name - - -def test_get_model_versions( - model_registry: ModelRegistry, - model_version: Mapped, - registered_model: Mapped, -): - rm_id = model_registry._store._mlmd_store.put_contexts([registered_model.proto])[0] - - model_version.proto.name = f"{rm_id}:version" - mv1_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model_version.proto.name = f"{rm_id}:version2" - mv2_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - - model_registry._store._mlmd_store.put_parent_contexts( - [ - ParentContext(parent_id=rm_id, child_id=mv1_id), - ParentContext(parent_id=rm_id, child_id=mv2_id), - ] - ) - - mlmd_mvs = model_registry.get_model_versions(str(rm_id)) - assert len(mlmd_mvs) == 2 - assert mlmd_mvs[0].id in [str(mv1_id), str(mv2_id)] - - -def test_upsert_model_artifact( - monkeypatch, model_registry: ModelRegistry, model: Mapped, model_version: Mapped -): - monkeypatch.setattr(ModelArtifact, "mlmd_name_prefix", "test_prefix") - - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - mv_id = str(mv_id) - - model_registry.upsert_model_artifact(model.py, mv_id) - - ma_proto = model_registry._store._mlmd_store.get_artifact_by_type_and_name( - ModelArtifact.get_proto_type_name(), f"test_prefix:{model.proto.name}" - ) - assert ma_proto is not None - assert model.py.id == str(ma_proto.id) - assert model.py.name != ma_proto.name - - -def test_upsert_duplicate_model_artifact_with_different_version( - model_registry: ModelRegistry, model: Mapped, model_version: Mapped -): - mv1_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - mv1_id = str(mv1_id) - - model_version.proto.name = "version2" - mv2_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - mv2_id = str(mv2_id) - - ma1 = evolve(model.py) - model_registry.upsert_model_artifact(ma1, mv1_id) - ma2 = evolve(model.py) - model_registry.upsert_model_artifact(ma2, mv2_id) + assert rm.id is not None - ma_protos = model_registry._store._mlmd_store.get_artifacts_by_id( - [int(ma1.id), int(ma2.id)] - ) - assert ma1.name == ma2.name - assert ma1.name != str(ma_protos[0].name) - assert ma2.name != str(ma_protos[1].name) + mr_api = mr_client._api + assert (mv := mr_api.get_model_version_by_params(rm.id, version)) is not None + assert mr_api.get_model_artifact_by_params(mv.id) is not None -def test_upsert_duplicate_model_artifact_with_same_version( - model_registry: ModelRegistry, model: Mapped, model_version: Mapped -): - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - mv_id = str(mv_id) +def test_register_existing_version(mr_client: ModelRegistry): + params = { + "name": "test_model", + "uri": "s3", + "model_format_name": "test_format", + "model_format_version": "test_version", + "version": "1.0.0", + } + mr_client.register_model(**params) - ma1 = evolve(model.py) - model_registry.upsert_model_artifact(ma1, mv_id) - ma2 = evolve(model.py) with pytest.raises(StoreException): - model_registry.upsert_model_artifact(ma2, mv_id) - - -def test_get_model_artifact_by_id(model_registry: ModelRegistry, model: Mapped): - model.proto.name = f"test_prefix:{model.proto.name}" - id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - id = str(id) - - mlmd_ma = model_registry.get_model_artifact_by_id(id) - - assert mlmd_ma.id == id - assert mlmd_ma.name == model.py.name - assert mlmd_ma.name != model.proto.name - + mr_client.register_model(**params) -def test_get_model_artifact_by_model_version_id( - model_registry: ModelRegistry, model: Mapped, model_version: Mapped -): - mv_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - model.proto.name = f"test_prefix:{model.proto.name}" - ma_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] +def test_get(mr_client: ModelRegistry): + name = "test_model" + version = "1.0.0" - model_registry._store._mlmd_store.put_attributions_and_associations( - [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + rm = mr_client.register_model( + name, + "s3", + model_format_name="test_format", + model_format_version="test_version", + version=version, ) - mlmd_ma = model_registry.get_model_artifact_by_params(model_version_id=str(mv_id)) + assert rm.id == mr_client.get_registered_model(name).id - assert mlmd_ma.id == str(ma_id) - assert mlmd_ma.name == model.py.name - assert mlmd_ma.name != model.proto.name - - -def test_get_model_artifact_by_external_id( - model_registry: ModelRegistry, model: Mapped -): - model.proto.name = f"test_prefix:{model.proto.name}" - model.proto.external_id = "external_id" - model.py.external_id = "external_id" - - id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - id = str(id) - - mlmd_ma = model_registry.get_model_artifact_by_params( - external_id=model.py.external_id - ) - - assert mlmd_ma.id == id - assert mlmd_ma.name == model.py.name - assert mlmd_ma.name != model.proto.name - - -def test_get_all_model_artifacts(model_registry: ModelRegistry, model: Mapped): - model.proto.name = "test_prefix:model1" - ma1_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - model.proto.name = "test_prefix:model2" - ma2_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - - mlmd_mas = model_registry.get_model_artifacts() - assert len(mlmd_mas) == 2 - assert mlmd_mas[0].id in [str(ma1_id), str(ma2_id)] - - -def test_get_model_artifacts_by_mv_id( - model_registry: ModelRegistry, model: Mapped, model_version: Mapped -): - mv1_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - - model_version.proto.name = "version2" - mv2_id = model_registry._store._mlmd_store.put_contexts([model_version.proto])[0] - - model.proto.name = "test_prefix:model1" - ma1_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - model.proto.name = "test_prefix:model2" - ma2_id = model_registry._store._mlmd_store.put_artifacts([model.proto])[0] - - model_registry._store._mlmd_store.put_attributions_and_associations( - [ - Attribution(context_id=mv1_id, artifact_id=ma1_id), - Attribution(context_id=mv2_id, artifact_id=ma2_id), - ], - [], - ) + mr_api = mr_client._api + mv = mr_api.get_model_version_by_params(rm.id, version) + ma = mr_api.get_model_artifact_by_params(mv.id) - mlmd_mas = model_registry.get_model_artifacts(str(mv1_id)) - assert len(mlmd_mas) == 1 - assert mlmd_mas[0].id == str(ma1_id) + assert mv.id == mr_client.get_model_version(name, version).id + assert ma.id == mr_client.get_model_artifact(name, version).id diff --git a/clients/python/tests/test_core.py b/clients/python/tests/test_core.py new file mode 100644 index 00000000..b35d7e8e --- /dev/null +++ b/clients/python/tests/test_core.py @@ -0,0 +1,344 @@ +"""Tests for user facing model registry APIs.""" + +import pytest +from attrs import evolve +from ml_metadata.proto import ( + Artifact, + Attribution, + Context, + ParentContext, +) +from model_registry.core import ModelRegistryAPIClient +from model_registry.exceptions import StoreException +from model_registry.store import MLMDStore +from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel + +from . import Mapped + + +@pytest.fixture() +def model(store_wrapper: MLMDStore) -> Mapped: + art = Artifact() + # we can't test the name directly as it's prefixed + art.name = "model" + art.type_id = store_wrapper.get_type_id( + Artifact, ModelArtifact.get_proto_type_name() + ) + + art.uri = "uri" + + return Mapped(art, ModelArtifact("model", "uri")) + + +@pytest.fixture() +def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: + ctx = Context() + # we can't test the name directly as it's prefixed + ctx.name = "version" + ctx.type_id = store_wrapper.get_type_id(Context, ModelVersion.get_proto_type_name()) + ctx.properties["author"].string_value = "author" + ctx.properties["model_name"].string_value = model.py.name + + return Mapped(ctx, ModelVersion(model.py.name, "version", "author")) + + +@pytest.fixture() +def registered_model(store_wrapper: MLMDStore, model: Mapped) -> Mapped: + ctx = Context() + ctx.name = model.py.name + ctx.type_id = store_wrapper.get_type_id( + Context, RegisteredModel.get_proto_type_name() + ) + + return Mapped(ctx, RegisteredModel(model.py.name)) + + +# TODO: should we test insert/update separately? +def test_upsert_registered_model( + mr_api: ModelRegistryAPIClient, registered_model: Mapped +): + mr_api.upsert_registered_model(registered_model.py) + + rm_proto = mr_api._store._mlmd_store.get_context_by_type_and_name( + RegisteredModel.get_proto_type_name(), registered_model.proto.name + ) + assert rm_proto is not None + assert registered_model.py.id == str(rm_proto.id) + assert registered_model.py.name == rm_proto.name + + +def test_get_registered_model_by_id( + mr_api: ModelRegistryAPIClient, + registered_model: Mapped, +): + rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] + + mlmd_rm = mr_api.get_registered_model_by_id(str(rm_id)) + assert mlmd_rm.id == str(rm_id) + assert mlmd_rm.name == registered_model.py.name + assert mlmd_rm.name == registered_model.proto.name + + +def test_get_registered_model_by_name( + mr_api: ModelRegistryAPIClient, + registered_model: Mapped, +): + rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] + + mlmd_rm = mr_api.get_registered_model_by_params(name=registered_model.py.name) + assert mlmd_rm.id == str(rm_id) + assert mlmd_rm.name == registered_model.py.name + assert mlmd_rm.name == registered_model.proto.name + + +def test_get_registered_model_by_external_id( + mr_api: ModelRegistryAPIClient, + registered_model: Mapped, +): + registered_model.py.external_id = "external_id" + registered_model.proto.external_id = "external_id" + rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] + + mlmd_rm = mr_api.get_registered_model_by_params( + external_id=registered_model.py.external_id + ) + assert mlmd_rm.id == str(rm_id) + assert mlmd_rm.name == registered_model.py.name + assert mlmd_rm.name == registered_model.proto.name + + +def test_get_registered_models( + mr_api: ModelRegistryAPIClient, registered_model: Mapped +): + rm1_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] + registered_model.proto.name = "model2" + rm2_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] + + mlmd_rms = mr_api.get_registered_models() + assert len(mlmd_rms) == 2 + assert mlmd_rms[0].id in [str(rm1_id), str(rm2_id)] + + +def test_upsert_model_version( + mr_api: ModelRegistryAPIClient, + model_version: Mapped, + registered_model: Mapped, +): + rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] + rm_id = str(rm_id) + + mr_api.upsert_model_version(model_version.py, rm_id) + + mv_proto = mr_api._store._mlmd_store.get_context_by_type_and_name( + ModelVersion.get_proto_type_name(), f"{rm_id}:{model_version.proto.name}" + ) + assert mv_proto is not None + assert model_version.py.id == str(mv_proto.id) + assert model_version.py.version != mv_proto.name + + +def test_get_model_version_by_id(mr_api: ModelRegistryAPIClient, model_version: Mapped): + model_version.proto.name = f"1:{model_version.proto.name}" + ctx_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + + id = str(ctx_id) + mlmd_mv = mr_api.get_model_version_by_id(id) + assert mlmd_mv.id == id + assert mlmd_mv.name == model_version.py.name + assert mlmd_mv.version != model_version.proto.name + + +def test_get_model_version_by_name( + mr_api: ModelRegistryAPIClient, model_version: Mapped +): + model_version.proto.name = f"1:{model_version.proto.name}" + mv_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + + mlmd_mv = mr_api.get_model_version_by_params( + registered_model_id="1", version=model_version.py.name + ) + assert mlmd_mv.id == str(mv_id) + assert mlmd_mv.name == model_version.py.name + assert mlmd_mv.name != model_version.proto.name + + +def test_get_model_version_by_external_id( + mr_api: ModelRegistryAPIClient, model_version: Mapped +): + model_version.proto.name = f"1:{model_version.proto.name}" + model_version.proto.external_id = "external_id" + model_version.py.external_id = "external_id" + mv_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + + mlmd_mv = mr_api.get_model_version_by_params( + external_id=model_version.py.external_id + ) + assert mlmd_mv.id == str(mv_id) + assert mlmd_mv.name == model_version.py.name + assert mlmd_mv.name != model_version.proto.name + + +def test_get_model_versions( + mr_api: ModelRegistryAPIClient, + model_version: Mapped, + registered_model: Mapped, +): + rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] + + model_version.proto.name = f"{rm_id}:version" + mv1_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + model_version.proto.name = f"{rm_id}:version2" + mv2_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + + mr_api._store._mlmd_store.put_parent_contexts( + [ + ParentContext(parent_id=rm_id, child_id=mv1_id), + ParentContext(parent_id=rm_id, child_id=mv2_id), + ] + ) + + mlmd_mvs = mr_api.get_model_versions(str(rm_id)) + assert len(mlmd_mvs) == 2 + assert mlmd_mvs[0].id in [str(mv1_id), str(mv2_id)] + + +def test_upsert_model_artifact( + monkeypatch, + mr_api: ModelRegistryAPIClient, + model: Mapped, + model_version: Mapped, +): + monkeypatch.setattr(ModelArtifact, "mlmd_name_prefix", "test_prefix") + + mv_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + mv_id = str(mv_id) + + mr_api.upsert_model_artifact(model.py, mv_id) + + ma_proto = mr_api._store._mlmd_store.get_artifact_by_type_and_name( + ModelArtifact.get_proto_type_name(), f"test_prefix:{model.proto.name}" + ) + assert ma_proto is not None + assert model.py.id == str(ma_proto.id) + assert model.py.name != ma_proto.name + + +def test_upsert_duplicate_model_artifact_with_different_version( + mr_api: ModelRegistryAPIClient, model: Mapped, model_version: Mapped +): + mv1_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + mv1_id = str(mv1_id) + + model_version.proto.name = "version2" + mv2_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + mv2_id = str(mv2_id) + + ma1 = evolve(model.py) + mr_api.upsert_model_artifact(ma1, mv1_id) + ma2 = evolve(model.py) + mr_api.upsert_model_artifact(ma2, mv2_id) + + ma_protos = mr_api._store._mlmd_store.get_artifacts_by_id( + [int(ma1.id), int(ma2.id)] + ) + assert ma1.name == ma2.name + assert ma1.name != str(ma_protos[0].name) + assert ma2.name != str(ma_protos[1].name) + + +def test_upsert_duplicate_model_artifact_with_same_version( + mr_api: ModelRegistryAPIClient, model: Mapped, model_version: Mapped +): + mv_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + mv_id = str(mv_id) + + ma1 = evolve(model.py) + mr_api.upsert_model_artifact(ma1, mv_id) + ma2 = evolve(model.py) + with pytest.raises(StoreException): + mr_api.upsert_model_artifact(ma2, mv_id) + + +def test_get_model_artifact_by_id(mr_api: ModelRegistryAPIClient, model: Mapped): + model.proto.name = f"test_prefix:{model.proto.name}" + id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] + id = str(id) + + mlmd_ma = mr_api.get_model_artifact_by_id(id) + + assert mlmd_ma.id == id + assert mlmd_ma.name == model.py.name + assert mlmd_ma.name != model.proto.name + + +def test_get_model_artifact_by_model_version_id( + mr_api: ModelRegistryAPIClient, model: Mapped, model_version: Mapped +): + mv_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + + model.proto.name = f"test_prefix:{model.proto.name}" + ma_id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] + + mr_api._store._mlmd_store.put_attributions_and_associations( + [Attribution(context_id=mv_id, artifact_id=ma_id)], [] + ) + + mlmd_ma = mr_api.get_model_artifact_by_params(model_version_id=str(mv_id)) + + assert mlmd_ma.id == str(ma_id) + assert mlmd_ma.name == model.py.name + assert mlmd_ma.name != model.proto.name + + +def test_get_model_artifact_by_external_id( + mr_api: ModelRegistryAPIClient, model: Mapped +): + model.proto.name = f"test_prefix:{model.proto.name}" + model.proto.external_id = "external_id" + model.py.external_id = "external_id" + + id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] + id = str(id) + + mlmd_ma = mr_api.get_model_artifact_by_params(external_id=model.py.external_id) + + assert mlmd_ma.id == id + assert mlmd_ma.name == model.py.name + assert mlmd_ma.name != model.proto.name + + +def test_get_all_model_artifacts(mr_api: ModelRegistryAPIClient, model: Mapped): + model.proto.name = "test_prefix:model1" + ma1_id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] + model.proto.name = "test_prefix:model2" + ma2_id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] + + mlmd_mas = mr_api.get_model_artifacts() + assert len(mlmd_mas) == 2 + assert mlmd_mas[0].id in [str(ma1_id), str(ma2_id)] + + +def test_get_model_artifacts_by_mv_id( + mr_api: ModelRegistryAPIClient, model: Mapped, model_version: Mapped +): + mv1_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + + model_version.proto.name = "version2" + mv2_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] + + model.proto.name = "test_prefix:model1" + ma1_id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] + model.proto.name = "test_prefix:model2" + ma2_id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] + + mr_api._store._mlmd_store.put_attributions_and_associations( + [ + Attribution(context_id=mv1_id, artifact_id=ma1_id), + Attribution(context_id=mv2_id, artifact_id=ma2_id), + ], + [], + ) + + mlmd_mas = mr_api.get_model_artifacts(str(mv1_id)) + assert len(mlmd_mas) == 1 + assert mlmd_mas[0].id == str(ma1_id) From ee6455355f140e3843b56bd17e4185a4e7551b7a Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 30 Nov 2023 09:52:34 +0100 Subject: [PATCH 174/254] Improve core testing using single test container (#213) * Improve core testing using single test container Signed-off-by: Andrea Lamparelli * Update pkg/core/core_test.go Co-authored-by: Matteo Mortari --------- Signed-off-by: Andrea Lamparelli Co-authored-by: Matteo Mortari --- internal/testutils/test_container_utils.go | 37 +- pkg/core/core_test.go | 1935 +++++++++----------- 2 files changed, 903 insertions(+), 1069 deletions(-) diff --git a/internal/testutils/test_container_utils.go b/internal/testutils/test_container_utils.go index aa5c1b53..42671550 100644 --- a/internal/testutils/test_container_utils.go +++ b/internal/testutils/test_container_utils.go @@ -21,7 +21,12 @@ const ( testConfigFolder = "test/config/ml-metadata" ) -func clearMetadataSqliteDB(wd string) error { +func ClearMetadataSqliteDB() error { + wd, err := getTestConfigWorkingDir() + if err != nil { + return err + } + if err := os.Remove(fmt.Sprintf("%s/%s", wd, sqliteFile)); err != nil { return fmt.Errorf("expected to clear sqlite file but didn't find: %v", err) } @@ -39,19 +44,25 @@ func fileExists(filePath string) (bool, error) { return false, err } -// SetupMLMDTestContainer creates a MLMD gRPC test container -// Returns -// - gRPC client connection to the test container -// - ml-metadata client used to double check the database -// - teardown function -func SetupMLMDTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { - ctx := context.Background() +func getTestConfigWorkingDir() (string, error) { wd, err := os.Getwd() + if err != nil { + return "", err + } + return fmt.Sprintf("%s/../../%s", wd, testConfigFolder), nil +} + +// SetupMLMetadataTestContainer setup a test container for MLMD server exposing gRPC interface +// Returns: +// - The test container gRPC address : +// - The teardown function to close and teardown the test container +func SetupMLMetadataTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { + ctx := context.Background() + wd, err := getTestConfigWorkingDir() if err != nil { t.Errorf("error getting working directory: %v", err) } - wd = fmt.Sprintf("%s/../../%s", wd, testConfigFolder) - t.Logf("using working directory: %s", wd) + // t.Logf("using working directory: %s", wd) // when unhandled panics or other hard failures, could leave the DB in the directory // here we make sure it's not existing already, and that it was really cleanup by previous runs @@ -99,8 +110,9 @@ func SetupMLMDTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStore if err != nil { t.Error(err) } + mlmdAddr := fmt.Sprintf("%s:%s", mappedHost, mappedPort.Port()) - t.Log("MLMD test container setup at: ", mlmdAddr) + t.Log("MLMD test container running at: ", mlmdAddr) // setup grpc connection conn, err := grpc.DialContext( @@ -123,8 +135,5 @@ func SetupMLMDTestContainer(t *testing.T) (*grpc.ClientConn, proto.MetadataStore if err := mlmdgrpc.Terminate(ctx); err != nil { t.Error(err) } - if err := clearMetadataSqliteDB(wd); err != nil { - t.Error(err) - } } } diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index f0c2458b..f33baf5b 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -10,7 +10,7 @@ import ( "github.com/opendatahub-io/model-registry/internal/testutils" "github.com/opendatahub-io/model-registry/pkg/api" "github.com/opendatahub-io/model-registry/pkg/openapi" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/suite" "google.golang.org/grpc" ) @@ -45,12 +45,26 @@ var ( executionState string ) -func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataStoreServiceClient, func(t *testing.T)) { - if testing.Short() { - // skip these tests using -short param - t.Skip("skipping testing in short mode") +type CoreTestSuite struct { + suite.Suite + grpcConn *grpc.ClientConn + mlmdClient proto.MetadataStoreServiceClient +} + +func TestRunCoreTestSuite(t *testing.T) { + // before all + grpcConn, mlmdClient, teardown := testutils.SetupMLMetadataTestContainer(t) + defer teardown(t) + + coreTestSuite := CoreTestSuite{ + grpcConn: grpcConn, + mlmdClient: mlmdClient, } + suite.Run(t, &coreTestSuite) +} +// before each test case +func (suite *CoreTestSuite) SetupTest() { // initialize test variable before each test ascOrderDirection = "ASC" descOrderDirection = "DESC" @@ -73,20 +87,27 @@ func setup(t *testing.T) (*assert.Assertions, *grpc.ClientConn, proto.MetadataSt entityExternalId2 = "entityExternalID2" entityDescription = "lorem ipsum entity description" executionState = "RUNNING" +} - conn, client, teardown := testutils.SetupMLMDTestContainer(t) - return assert.New(t), conn, client, teardown +// after each test +// - remove the metadata sqlite file used by mlmd, this way mlmd will recreate it +func (suite *CoreTestSuite) AfterTest(suiteName, testName string) { + if err := testutils.ClearMetadataSqliteDB(); err != nil { + suite.Error(err) + } } -// initialize model registry service and assert no error is thrown -func initModelRegistryService(assertion *assert.Assertions, conn *grpc.ClientConn) api.ModelRegistryApi { - service, err := NewModelRegistryService(conn) - assertion.Nilf(err, "error creating core service: %v", err) - return service +func (suite *CoreTestSuite) setupModelRegistryService() *ModelRegistryService { + // setup model registry service + service, err := NewModelRegistryService(suite.grpcConn) + suite.Nilf(err, "error creating core service: %v", err) + mrService, ok := service.(*ModelRegistryService) + suite.True(ok) + return mrService } // utility function that register a new simple model and return its ID -func registerModel(assertion *assert.Assertions, service api.ModelRegistryApi, overrideModelName *string, overrideExternalId *string) string { +func (suite *CoreTestSuite) registerModel(service api.ModelRegistryApi, overrideModelName *string, overrideExternalId *string) string { registeredModel := &openapi.RegisteredModel{ Name: &modelName, ExternalID: &modelExternalId, @@ -110,13 +131,13 @@ func registerModel(assertion *assert.Assertions, service api.ModelRegistryApi, o // test createdModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) return *createdModel.Id } // utility function that register a new simple ServingEnvironment and return its ID -func registerServingEnvironment(assertion *assert.Assertions, service api.ModelRegistryApi, overrideName *string, overrideExternalId *string) string { +func (suite *CoreTestSuite) registerServingEnvironment(service api.ModelRegistryApi, overrideName *string, overrideExternalId *string) string { eutName := "Simple ServingEnvironment" eutExtID := "Simple ServingEnvironment ExtID" eut := &openapi.ServingEnvironment{ @@ -142,21 +163,20 @@ func registerServingEnvironment(assertion *assert.Assertions, service api.ModelR // test createdEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) return *createdEntity.Id } // utility function that register a new simple model and return its ID -func registerModelVersion( - assertion *assert.Assertions, +func (suite *CoreTestSuite) registerModelVersion( service api.ModelRegistryApi, overrideModelName *string, overrideExternalId *string, overrideVersionName *string, overrideVersionExtId *string, ) string { - registeredModelId := registerModel(assertion, service, overrideModelName, overrideExternalId) + registeredModelId := suite.registerModel(service, overrideModelName, overrideExternalId) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -174,14 +194,14 @@ func registerModelVersion( } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating model version: %v", err) + suite.Nilf(err, "error creating model version: %v", err) return *createdVersion.Id } // utility function that register a new simple ServingEnvironment and return its ID -func registerInferenceService(assertion *assert.Assertions, service api.ModelRegistryApi, registerdModelId string, overrideParentResourceName *string, overrideParentResourceExternalId *string, overrideName *string, overrideExternalId *string) string { - servingEnvironmentId := registerServingEnvironment(assertion, service, overrideParentResourceName, overrideParentResourceExternalId) +func (suite *CoreTestSuite) registerInferenceService(service api.ModelRegistryApi, registerdModelId string, overrideParentResourceName *string, overrideParentResourceExternalId *string, overrideName *string, overrideExternalId *string) string { + servingEnvironmentId := suite.registerServingEnvironment(service, overrideParentResourceName, overrideParentResourceExternalId) eutName := "simpleInferenceService" eutExtID := "simpleInferenceService ExtID" @@ -208,15 +228,13 @@ func registerInferenceService(assertion *assert.Assertions, service api.ModelReg // test createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating InferenceService: %v", err) + suite.Nilf(err, "error creating InferenceService: %v", err) return *createdEntity.Id } -func TestModelRegistryStartupWithExistingEmptyTypes(t *testing.T) { +func (suite *CoreTestSuite) TestModelRegistryStartupWithExistingEmptyTypes() { ctx := context.Background() - assertion, conn, client, teardown := setup(t) - defer teardown(t) // create all types without props registeredModelReq := proto.PutContextTypeRequest{ @@ -256,145 +274,139 @@ func TestModelRegistryStartupWithExistingEmptyTypes(t *testing.T) { }, } - _, err := client.PutContextType(context.Background(), ®isteredModelReq) - assertion.Nil(err) - _, err = client.PutContextType(context.Background(), &modelVersionReq) - assertion.Nil(err) - _, err = client.PutArtifactType(context.Background(), &modelArtifactReq) - assertion.Nil(err) - _, err = client.PutContextType(context.Background(), &servingEnvironmentReq) - assertion.Nil(err) - _, err = client.PutContextType(context.Background(), &inferenceServiceReq) - assertion.Nil(err) - _, err = client.PutExecutionType(context.Background(), &serveModelReq) - assertion.Nil(err) + _, err := suite.mlmdClient.PutContextType(context.Background(), ®isteredModelReq) + suite.Nil(err) + _, err = suite.mlmdClient.PutContextType(context.Background(), &modelVersionReq) + suite.Nil(err) + _, err = suite.mlmdClient.PutArtifactType(context.Background(), &modelArtifactReq) + suite.Nil(err) + _, err = suite.mlmdClient.PutContextType(context.Background(), &servingEnvironmentReq) + suite.Nil(err) + _, err = suite.mlmdClient.PutContextType(context.Background(), &inferenceServiceReq) + suite.Nil(err) + _, err = suite.mlmdClient.PutExecutionType(context.Background(), &serveModelReq) + suite.Nil(err) // check empty props - regModelResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + regModelResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: registeredModelTypeName, }) - modelVersionResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + modelVersionResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: modelVersionTypeName, }) - modelArtifactResp, _ := client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + modelArtifactResp, _ := suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, }) - servingEnvResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + servingEnvResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: servingEnvironmentTypeName, }) - inferenceServiceResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + inferenceServiceResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: inferenceServiceTypeName, }) - serveModelResp, _ := client.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ + serveModelResp, _ := suite.mlmdClient.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ TypeName: serveModelTypeName, }) - assertion.Equal(0, len(regModelResp.ContextType.Properties)) - assertion.Equal(0, len(modelVersionResp.ContextType.Properties)) - assertion.Equal(0, len(modelArtifactResp.ArtifactType.Properties)) - assertion.Equal(0, len(servingEnvResp.ContextType.Properties)) - assertion.Equal(0, len(inferenceServiceResp.ContextType.Properties)) - assertion.Equal(0, len(serveModelResp.ExecutionType.Properties)) + suite.Equal(0, len(regModelResp.ContextType.Properties)) + suite.Equal(0, len(modelVersionResp.ContextType.Properties)) + suite.Equal(0, len(modelArtifactResp.ArtifactType.Properties)) + suite.Equal(0, len(servingEnvResp.ContextType.Properties)) + suite.Equal(0, len(inferenceServiceResp.ContextType.Properties)) + suite.Equal(0, len(serveModelResp.ExecutionType.Properties)) // create model registry service - _, err = NewModelRegistryService(conn) - assertion.Nil(err) + _, err = NewModelRegistryService(suite.grpcConn) + suite.Nil(err) // assure the types have been correctly setup at startup // check NOT empty props - regModelResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + regModelResp, _ = suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: registeredModelTypeName, }) - assertion.NotNilf(regModelResp.ContextType, "registered model type %s should exists", *registeredModelTypeName) - assertion.Equal(*registeredModelTypeName, *regModelResp.ContextType.Name) - assertion.Equal(2, len(regModelResp.ContextType.Properties)) + suite.NotNilf(regModelResp.ContextType, "registered model type %s should exists", *registeredModelTypeName) + suite.Equal(*registeredModelTypeName, *regModelResp.ContextType.Name) + suite.Equal(2, len(regModelResp.ContextType.Properties)) - modelVersionResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + modelVersionResp, _ = suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: modelVersionTypeName, }) - assertion.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) - assertion.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) - assertion.Equal(5, len(modelVersionResp.ContextType.Properties)) + suite.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) + suite.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) + suite.Equal(5, len(modelVersionResp.ContextType.Properties)) - modelArtifactResp, _ = client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + modelArtifactResp, _ = suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, }) - assertion.NotNilf(modelArtifactResp.ArtifactType, "model artifact type %s should exists", *modelArtifactTypeName) - assertion.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) - assertion.Equal(6, len(modelArtifactResp.ArtifactType.Properties)) + suite.NotNilf(modelArtifactResp.ArtifactType, "model artifact type %s should exists", *modelArtifactTypeName) + suite.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) + suite.Equal(6, len(modelArtifactResp.ArtifactType.Properties)) - servingEnvResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + servingEnvResp, _ = suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: servingEnvironmentTypeName, }) - assertion.NotNilf(servingEnvResp.ContextType, "serving environment type %s should exists", *servingEnvironmentTypeName) - assertion.Equal(*servingEnvironmentTypeName, *servingEnvResp.ContextType.Name) - assertion.Equal(1, len(servingEnvResp.ContextType.Properties)) + suite.NotNilf(servingEnvResp.ContextType, "serving environment type %s should exists", *servingEnvironmentTypeName) + suite.Equal(*servingEnvironmentTypeName, *servingEnvResp.ContextType.Name) + suite.Equal(1, len(servingEnvResp.ContextType.Properties)) - inferenceServiceResp, _ = client.GetContextType(ctx, &proto.GetContextTypeRequest{ + inferenceServiceResp, _ = suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: inferenceServiceTypeName, }) - assertion.NotNilf(inferenceServiceResp.ContextType, "inference service type %s should exists", *inferenceServiceTypeName) - assertion.Equal(*inferenceServiceTypeName, *inferenceServiceResp.ContextType.Name) - assertion.Equal(6, len(inferenceServiceResp.ContextType.Properties)) + suite.NotNilf(inferenceServiceResp.ContextType, "inference service type %s should exists", *inferenceServiceTypeName) + suite.Equal(*inferenceServiceTypeName, *inferenceServiceResp.ContextType.Name) + suite.Equal(6, len(inferenceServiceResp.ContextType.Properties)) - serveModelResp, _ = client.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ + serveModelResp, _ = suite.mlmdClient.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ TypeName: serveModelTypeName, }) - assertion.NotNilf(serveModelResp.ExecutionType, "serve model type %s should exists", *serveModelTypeName) - assertion.Equal(*serveModelTypeName, *serveModelResp.ExecutionType.Name) - assertion.Equal(2, len(serveModelResp.ExecutionType.Properties)) + suite.NotNilf(serveModelResp.ExecutionType, "serve model type %s should exists", *serveModelTypeName) + suite.Equal(*serveModelTypeName, *serveModelResp.ExecutionType.Name) + suite.Equal(2, len(serveModelResp.ExecutionType.Properties)) } -func TestModelRegistryTypes(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestModelRegistryTypes() { // create model registry service - _ = initModelRegistryService(assertion, conn) + _ = suite.setupModelRegistryService() // assure the types have been correctly setup at startup ctx := context.Background() - regModelResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + regModelResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: registeredModelTypeName, }) - assertion.NotNilf(regModelResp.ContextType, "registered model type %s should exists", *registeredModelTypeName) - assertion.Equal(*registeredModelTypeName, *regModelResp.ContextType.Name) + suite.NotNilf(regModelResp.ContextType, "registered model type %s should exists", *registeredModelTypeName) + suite.Equal(*registeredModelTypeName, *regModelResp.ContextType.Name) - modelVersionResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + modelVersionResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: modelVersionTypeName, }) - assertion.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) - assertion.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) + suite.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) + suite.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) - modelArtifactResp, _ := client.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + modelArtifactResp, _ := suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, }) - assertion.NotNilf(modelArtifactResp.ArtifactType, "model version type %s should exists", *modelArtifactTypeName) - assertion.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) + suite.NotNilf(modelArtifactResp.ArtifactType, "model version type %s should exists", *modelArtifactTypeName) + suite.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) - servingEnvResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + servingEnvResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: servingEnvironmentTypeName, }) - assertion.NotNilf(servingEnvResp.ContextType, "serving environment type %s should exists", *servingEnvironmentTypeName) - assertion.Equal(*servingEnvironmentTypeName, *servingEnvResp.ContextType.Name) + suite.NotNilf(servingEnvResp.ContextType, "serving environment type %s should exists", *servingEnvironmentTypeName) + suite.Equal(*servingEnvironmentTypeName, *servingEnvResp.ContextType.Name) - inferenceServiceResp, _ := client.GetContextType(ctx, &proto.GetContextTypeRequest{ + inferenceServiceResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: inferenceServiceTypeName, }) - assertion.NotNilf(inferenceServiceResp.ContextType, "inference service type %s should exists", *inferenceServiceTypeName) - assertion.Equal(*inferenceServiceTypeName, *inferenceServiceResp.ContextType.Name) + suite.NotNilf(inferenceServiceResp.ContextType, "inference service type %s should exists", *inferenceServiceTypeName) + suite.Equal(*inferenceServiceTypeName, *inferenceServiceResp.ContextType.Name) - serveModelResp, _ := client.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ + serveModelResp, _ := suite.mlmdClient.GetExecutionType(ctx, &proto.GetExecutionTypeRequest{ TypeName: serveModelTypeName, }) - assertion.NotNilf(serveModelResp.ExecutionType, "serve model type %s should exists", *serveModelTypeName) - assertion.Equal(*serveModelTypeName, *serveModelResp.ExecutionType.Name) + suite.NotNilf(serveModelResp.ExecutionType, "serve model type %s should exists", *serveModelTypeName) + suite.Equal(*serveModelTypeName, *serveModelResp.ExecutionType.Name) } -func TestModelRegistryFailureForOmittedFieldInRegisteredModel(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInRegisteredModel() { registeredModelReq := proto.PutContextTypeRequest{ CanAddFields: canAddFields, ContextType: &proto.ContextType{ @@ -405,19 +417,16 @@ func TestModelRegistryFailureForOmittedFieldInRegisteredModel(t *testing.T) { }, } - _, err := client.PutContextType(context.Background(), ®isteredModelReq) - assertion.Nil(err) + _, err := suite.mlmdClient.PutContextType(context.Background(), ®isteredModelReq) + suite.Nil(err) // create model registry service - _, err = NewModelRegistryService(conn) - assertion.NotNil(err) - assertion.Regexp("error setting up context type odh.RegisteredModel: rpc error: code = AlreadyExists.*", err.Error()) + _, err = NewModelRegistryService(suite.grpcConn) + suite.NotNil(err) + suite.Regexp("error setting up context type odh.RegisteredModel: rpc error: code = AlreadyExists.*", err.Error()) } -func TestModelRegistryFailureForOmittedFieldInModelVersion(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInModelVersion() { modelVersionReq := proto.PutContextTypeRequest{ CanAddFields: canAddFields, ContextType: &proto.ContextType{ @@ -428,19 +437,16 @@ func TestModelRegistryFailureForOmittedFieldInModelVersion(t *testing.T) { }, } - _, err := client.PutContextType(context.Background(), &modelVersionReq) - assertion.Nil(err) + _, err := suite.mlmdClient.PutContextType(context.Background(), &modelVersionReq) + suite.Nil(err) // create model registry service - _, err = NewModelRegistryService(conn) - assertion.NotNil(err) - assertion.Regexp("error setting up context type odh.ModelVersion: rpc error: code = AlreadyExists.*", err.Error()) + _, err = NewModelRegistryService(suite.grpcConn) + suite.NotNil(err) + suite.Regexp("error setting up context type odh.ModelVersion: rpc error: code = AlreadyExists.*", err.Error()) } -func TestModelRegistryFailureForOmittedFieldInModelArtifact(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInModelArtifact() { modelArtifactReq := proto.PutArtifactTypeRequest{ CanAddFields: canAddFields, ArtifactType: &proto.ArtifactType{ @@ -451,19 +457,16 @@ func TestModelRegistryFailureForOmittedFieldInModelArtifact(t *testing.T) { }, } - _, err := client.PutArtifactType(context.Background(), &modelArtifactReq) - assertion.Nil(err) + _, err := suite.mlmdClient.PutArtifactType(context.Background(), &modelArtifactReq) + suite.Nil(err) // create model registry service - _, err = NewModelRegistryService(conn) - assertion.NotNil(err) - assertion.Regexp("error setting up artifact type odh.ModelArtifact: rpc error: code = AlreadyExists.*", err.Error()) + _, err = NewModelRegistryService(suite.grpcConn) + suite.NotNil(err) + suite.Regexp("error setting up artifact type odh.ModelArtifact: rpc error: code = AlreadyExists.*", err.Error()) } -func TestModelRegistryFailureForOmittedFieldInServingEnvironment(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInServingEnvironment() { servingEnvironmentReq := proto.PutContextTypeRequest{ CanAddFields: canAddFields, ContextType: &proto.ContextType{ @@ -473,19 +476,16 @@ func TestModelRegistryFailureForOmittedFieldInServingEnvironment(t *testing.T) { }, }, } - _, err := client.PutContextType(context.Background(), &servingEnvironmentReq) - assertion.Nil(err) + _, err := suite.mlmdClient.PutContextType(context.Background(), &servingEnvironmentReq) + suite.Nil(err) // create model registry service - _, err = NewModelRegistryService(conn) - assertion.NotNil(err) - assertion.Regexp("error setting up context type odh.ServingEnvironment: rpc error: code = AlreadyExists.*", err.Error()) + _, err = NewModelRegistryService(suite.grpcConn) + suite.NotNil(err) + suite.Regexp("error setting up context type odh.ServingEnvironment: rpc error: code = AlreadyExists.*", err.Error()) } -func TestModelRegistryFailureForOmittedFieldInInferenceService(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInInferenceService() { inferenceServiceReq := proto.PutContextTypeRequest{ CanAddFields: canAddFields, ContextType: &proto.ContextType{ @@ -496,19 +496,16 @@ func TestModelRegistryFailureForOmittedFieldInInferenceService(t *testing.T) { }, } - _, err := client.PutContextType(context.Background(), &inferenceServiceReq) - assertion.Nil(err) + _, err := suite.mlmdClient.PutContextType(context.Background(), &inferenceServiceReq) + suite.Nil(err) // create model registry service - _, err = NewModelRegistryService(conn) - assertion.NotNil(err) - assertion.Regexp("error setting up context type odh.InferenceService: rpc error: code = AlreadyExists.*", err.Error()) + _, err = NewModelRegistryService(suite.grpcConn) + suite.NotNil(err) + suite.Regexp("error setting up context type odh.InferenceService: rpc error: code = AlreadyExists.*", err.Error()) } -func TestModelRegistryFailureForOmittedFieldInServeModel(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInServeModel() { serveModelReq := proto.PutExecutionTypeRequest{ CanAddFields: canAddFields, ExecutionType: &proto.ExecutionType{ @@ -519,23 +516,20 @@ func TestModelRegistryFailureForOmittedFieldInServeModel(t *testing.T) { }, } - _, err := client.PutExecutionType(context.Background(), &serveModelReq) - assertion.Nil(err) + _, err := suite.mlmdClient.PutExecutionType(context.Background(), &serveModelReq) + suite.Nil(err) // create model registry service - _, err = NewModelRegistryService(conn) - assertion.NotNil(err) - assertion.Regexp("error setting up execution type odh.ServeModel: rpc error: code = AlreadyExists.*", err.Error()) + _, err = NewModelRegistryService(suite.grpcConn) + suite.NotNil(err) + suite.Regexp("error setting up execution type odh.ServeModel: rpc error: code = AlreadyExists.*", err.Error()) } // REGISTERED MODELS -func TestCreateRegisteredModel(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateRegisteredModel() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() state := openapi.REGISTEREDMODELSTATE_ARCHIVED // register a new model @@ -557,35 +551,32 @@ func TestCreateRegisteredModel(t *testing.T) { createdModel, err := service.UpsertRegisteredModel(registeredModel) // checks - assertion.Nilf(err, "error creating registered model: %v", err) - assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") + suite.Nilf(err, "error creating registered model: %v", err) + suite.NotNilf(createdModel.Id, "created registered model should not have nil Id") createdModelId, _ := converter.StringToInt64(createdModel.Id) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{*createdModelId}, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] ctxId := converter.Int64ToString(ctx.Id) - assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") - assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") - assertion.Equal(modelExternalId, *ctx.ExternalId, "saved external id should match the provided one") - assertion.Equal(modelDescription, ctx.Properties["description"].GetStringValue(), "saved description should match the provided one") - assertion.Equal(string(state), ctx.Properties["state"].GetStringValue(), "saved state should match the provided one") - assertion.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + suite.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") + suite.Equal(modelName, *ctx.Name, "saved model name should match the provided one") + suite.Equal(modelExternalId, *ctx.ExternalId, "saved external id should match the provided one") + suite.Equal(modelDescription, ctx.Properties["description"].GetStringValue(), "saved description should match the provided one") + suite.Equal(string(state), ctx.Properties["state"].GetStringValue(), "saved state should match the provided one") + suite.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") } -func TestUpdateRegisteredModel(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateRegisteredModel() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new model registeredModel := &openapi.RegisteredModel{ @@ -604,14 +595,14 @@ func TestUpdateRegisteredModel(t *testing.T) { createdModel, err := service.UpsertRegisteredModel(registeredModel) // checks - assertion.Nilf(err, "error creating registered model: %v", err) - assertion.NotNilf(createdModel.Id, "created registered model should not have nil Id") + suite.Nilf(err, "error creating registered model: %v", err) + suite.NotNilf(createdModel.Id, "created registered model should not have nil Id") createdModelId, _ := converter.StringToInt64(createdModel.Id) // checks created model matches original one except for Id - assertion.Equal(*registeredModel.Name, *createdModel.Name, "returned model name should match the original one") - assertion.Equal(*registeredModel.ExternalID, *createdModel.ExternalID, "returned model external id should match the original one") - assertion.Equal(*registeredModel.CustomProperties, *createdModel.CustomProperties, "returned model custom props should match the original one") + suite.Equal(*registeredModel.Name, *createdModel.Name, "returned model name should match the original one") + suite.Equal(*registeredModel.ExternalID, *createdModel.ExternalID, "returned model external id should match the original one") + suite.Equal(*registeredModel.CustomProperties, *createdModel.CustomProperties, "returned model custom props should match the original one") // update existing model newModelExternalId := "newExternalId" @@ -626,56 +617,53 @@ func TestUpdateRegisteredModel(t *testing.T) { // update the model createdModel, err = service.UpsertRegisteredModel(createdModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) // still one registered model - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{*createdModelId}, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] ctxId := converter.Int64ToString(ctx.Id) - assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") - assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") - assertion.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") - assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + suite.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") + suite.Equal(modelName, *ctx.Name, "saved model name should match the provided one") + suite.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") + suite.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") // update the model keeping nil name newModelExternalId = "newNewExternalId" createdModel.ExternalID = &newModelExternalId createdModel.Name = nil createdModel, err = service.UpsertRegisteredModel(createdModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) // still one registered model - getAllResp, err = client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + getAllResp, err = suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") - ctxById, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err = suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{*createdModelId}, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx = ctxById.Contexts[0] ctxId = converter.Int64ToString(ctx.Id) - assertion.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") - assertion.Equal(modelName, *ctx.Name, "saved model name should match the provided one") - assertion.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") - assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + suite.Equal(*createdModel.Id, *ctxId, "returned model id should match the mlmd one") + suite.Equal(modelName, *ctx.Name, "saved model name should match the provided one") + suite.Equal(newModelExternalId, *ctx.ExternalId, "saved external id should match the provided one") + suite.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") } -func TestGetRegisteredModelById(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() state := openapi.REGISTEREDMODELSTATE_LIVE // register a new model @@ -696,36 +684,30 @@ func TestGetRegisteredModelById(t *testing.T) { createdModel, err := service.UpsertRegisteredModel(registeredModel) // checks - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) getModelById, err := service.GetRegisteredModelById(*createdModel.Id) - assertion.Nilf(err, "error getting registered model by id %s: %v", *createdModel.Id, err) + suite.Nilf(err, "error getting registered model by id %s: %v", *createdModel.Id, err) // checks created model matches original one except for Id - assertion.Equal(*registeredModel.Name, *getModelById.Name, "saved model name should match the original one") - assertion.Equal(*registeredModel.ExternalID, *getModelById.ExternalID, "saved model external id should match the original one") - assertion.Equal(*registeredModel.State, *getModelById.State, "saved model state should match the original one") - assertion.Equal(*registeredModel.CustomProperties, *getModelById.CustomProperties, "saved model custom props should match the original one") + suite.Equal(*registeredModel.Name, *getModelById.Name, "saved model name should match the original one") + suite.Equal(*registeredModel.ExternalID, *getModelById.ExternalID, "saved model external id should match the original one") + suite.Equal(*registeredModel.State, *getModelById.State, "saved model state should match the original one") + suite.Equal(*registeredModel.CustomProperties, *getModelById.CustomProperties, "saved model custom props should match the original one") } -func TestGetRegisteredModelByParamsWithNoResults(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelByParamsWithNoResults() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() _, err := service.GetRegisteredModelByParams(of("not-present"), nil) - assertion.NotNil(err) - assertion.Equal("no registered models found for name=not-present, externalId=", err.Error()) + suite.NotNil(err) + suite.Equal("no registered models found for name=not-present, externalId=", err.Error()) } -func TestGetRegisteredModelByParamsName(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelByParamsName() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new model registeredModel := &openapi.RegisteredModel{ @@ -734,20 +716,17 @@ func TestGetRegisteredModelByParamsName(t *testing.T) { } createdModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) byName, err := service.GetRegisteredModelByParams(&modelName, nil) - assertion.Nilf(err, "error getting registered model by name: %v", err) + suite.Nilf(err, "error getting registered model by name: %v", err) - assertion.Equalf(*createdModel.Id, *byName.Id, "the returned model id should match the retrieved by name") + suite.Equalf(*createdModel.Id, *byName.Id, "the returned model id should match the retrieved by name") } -func TestGetRegisteredModelByParamsExternalId(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelByParamsExternalId() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new model registeredModel := &openapi.RegisteredModel{ @@ -756,20 +735,17 @@ func TestGetRegisteredModelByParamsExternalId(t *testing.T) { } createdModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) byName, err := service.GetRegisteredModelByParams(nil, &modelExternalId) - assertion.Nilf(err, "error getting registered model by external id: %v", err) + suite.Nilf(err, "error getting registered model by external id: %v", err) - assertion.Equalf(*createdModel.Id, *byName.Id, "the returned model id should match the retrieved by name") + suite.Equalf(*createdModel.Id, *byName.Id, "the returned model id should match the retrieved by name") } -func TestGetRegisteredModelByEmptyParams(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelByEmptyParams() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new model registeredModel := &openapi.RegisteredModel{ @@ -778,19 +754,16 @@ func TestGetRegisteredModelByEmptyParams(t *testing.T) { } _, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) _, err = service.GetRegisteredModelByParams(nil, nil) - assertion.NotNil(err) - assertion.Equal("invalid parameters call, supply either name or externalId", err.Error()) + suite.NotNil(err) + suite.Equal("invalid parameters call, supply either name or externalId", err.Error()) } -func TestGetRegisteredModelsOrderedById(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelsOrderedById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() orderBy := "ID" @@ -801,51 +774,48 @@ func TestGetRegisteredModelsOrderedById(t *testing.T) { } _, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) newModelName := "PricingModel2" newModelExternalId := "myExternalId2" registeredModel.Name = &newModelName registeredModel.ExternalID = &newModelExternalId _, err = service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) newModelName = "PricingModel3" newModelExternalId = "myExternalId3" registeredModel.Name = &newModelName registeredModel.ExternalID = &newModelExternalId _, err = service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) orderedById, err := service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) - assertion.Nilf(err, "error getting registered models: %v", err) + suite.Nilf(err, "error getting registered models: %v", err) - assertion.Equal(3, int(orderedById.Size)) + suite.Equal(3, int(orderedById.Size)) for i := 0; i < int(orderedById.Size)-1; i++ { - assertion.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + suite.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) } orderedById, err = service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) - assertion.Nilf(err, "error getting registered models: %v", err) + suite.Nilf(err, "error getting registered models: %v", err) - assertion.Equal(3, int(orderedById.Size)) + suite.Equal(3, int(orderedById.Size)) for i := 0; i < int(orderedById.Size)-1; i++ { - assertion.Greater(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + suite.Greater(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) } } -func TestGetRegisteredModelsOrderedByLastUpdate(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelsOrderedByLastUpdate() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() orderBy := "LAST_UPDATE_TIME" @@ -856,56 +826,53 @@ func TestGetRegisteredModelsOrderedByLastUpdate(t *testing.T) { } firstModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) newModelName := "PricingModel2" newModelExternalId := "myExternalId2" registeredModel.Name = &newModelName registeredModel.ExternalID = &newModelExternalId secondModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) newModelName = "PricingModel3" newModelExternalId = "myExternalId3" registeredModel.Name = &newModelName registeredModel.ExternalID = &newModelExternalId thirdModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) // update second model secondModel.ExternalID = nil _, err = service.UpsertRegisteredModel(secondModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) orderedById, err := service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) - assertion.Nilf(err, "error getting registered models: %v", err) + suite.Nilf(err, "error getting registered models: %v", err) - assertion.Equal(3, int(orderedById.Size)) - assertion.Equal(*firstModel.Id, *orderedById.Items[0].Id) - assertion.Equal(*thirdModel.Id, *orderedById.Items[1].Id) - assertion.Equal(*secondModel.Id, *orderedById.Items[2].Id) + suite.Equal(3, int(orderedById.Size)) + suite.Equal(*firstModel.Id, *orderedById.Items[0].Id) + suite.Equal(*thirdModel.Id, *orderedById.Items[1].Id) + suite.Equal(*secondModel.Id, *orderedById.Items[2].Id) orderedById, err = service.GetRegisteredModels(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) - assertion.Nilf(err, "error getting registered models: %v", err) + suite.Nilf(err, "error getting registered models: %v", err) - assertion.Equal(3, int(orderedById.Size)) - assertion.Equal(*secondModel.Id, *orderedById.Items[0].Id) - assertion.Equal(*thirdModel.Id, *orderedById.Items[1].Id) - assertion.Equal(*firstModel.Id, *orderedById.Items[2].Id) + suite.Equal(3, int(orderedById.Size)) + suite.Equal(*secondModel.Id, *orderedById.Items[0].Id) + suite.Equal(*thirdModel.Id, *orderedById.Items[1].Id) + suite.Equal(*firstModel.Id, *orderedById.Items[2].Id) } -func TestGetRegisteredModelsWithPageSize(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelsWithPageSize() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() pageSize := int32(1) pageSize2 := int32(2) @@ -919,53 +886,50 @@ func TestGetRegisteredModelsWithPageSize(t *testing.T) { } firstModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) newModelName := "PricingModel2" newModelExternalId := "myExternalId2" registeredModel.Name = &newModelName registeredModel.ExternalID = &newModelExternalId secondModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) newModelName = "PricingModel3" newModelExternalId = "myExternalId3" registeredModel.Name = &newModelName registeredModel.ExternalID = &newModelExternalId thirdModel, err := service.UpsertRegisteredModel(registeredModel) - assertion.Nilf(err, "error creating registered model: %v", err) + suite.Nilf(err, "error creating registered model: %v", err) truncatedList, err := service.GetRegisteredModels(api.ListOptions{ PageSize: &pageSize, }) - assertion.Nilf(err, "error getting registered models: %v", err) + suite.Nilf(err, "error getting registered models: %v", err) - assertion.Equal(1, int(truncatedList.Size)) - assertion.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") - assertion.Equal(*firstModel.Id, *truncatedList.Items[0].Id) + suite.Equal(1, int(truncatedList.Size)) + suite.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") + suite.Equal(*firstModel.Id, *truncatedList.Items[0].Id) truncatedList, err = service.GetRegisteredModels(api.ListOptions{ PageSize: &pageSize2, NextPageToken: &truncatedList.NextPageToken, }) - assertion.Nilf(err, "error getting registered models: %v", err) + suite.Nilf(err, "error getting registered models: %v", err) - assertion.Equal(2, int(truncatedList.Size)) - assertion.Equal("", truncatedList.NextPageToken, "next page token should be empty as list item returned") - assertion.Equal(*secondModel.Id, *truncatedList.Items[0].Id) - assertion.Equal(*thirdModel.Id, *truncatedList.Items[1].Id) + suite.Equal(2, int(truncatedList.Size)) + suite.Equal("", truncatedList.NextPageToken, "next page token should be empty as list item returned") + suite.Equal(*secondModel.Id, *truncatedList.Items[0].Id) + suite.Equal(*thirdModel.Id, *truncatedList.Items[1].Id) } // MODEL VERSIONS -func TestCreateModelVersion(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateModelVersion() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) state := openapi.MODELVERSIONSTATE_LIVE modelVersion := &openapi.ModelVersion{ @@ -977,39 +941,36 @@ func TestCreateModelVersion(t *testing.T) { } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) - assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + suite.NotNilf(createdVersion.Id, "created model version should not have nil Id") createdVersionId, _ := converter.StringToInt64(createdVersion.Id) - byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + byId, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdVersionId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") - assertion.Equal(*createdVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") - assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") - assertion.Equal(versionExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") - assertion.Equal(modelVersionDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") - assertion.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") - assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) + suite.Equal(*createdVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") + suite.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") + suite.Equal(versionExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + suite.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") + suite.Equal(modelVersionDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") + suite.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") + suite.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") } -func TestCreateModelVersionFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateModelVersionFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() registeredModelId := "9999" @@ -1020,22 +981,19 @@ func TestCreateModelVersionFailure(t *testing.T) { } _, err := service.UpsertModelVersion(modelVersion, nil) - assertion.NotNil(err) - assertion.Equal("missing registered model id, cannot create model version without registered model", err.Error()) + suite.NotNil(err) + suite.Equal("missing registered model id, cannot create model version without registered model", err.Error()) _, err = service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.NotNil(err) - assertion.Equal("no registered model found for id 9999", err.Error()) + suite.NotNil(err) + suite.Equal("no registered model found for id 9999", err.Error()) } -func TestUpdateModelVersion(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateModelVersion() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -1044,9 +1002,9 @@ func TestUpdateModelVersion(t *testing.T) { } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) - assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + suite.NotNilf(createdVersion.Id, "created model version should not have nil Id") createdVersionId, _ := converter.StringToInt64(createdVersion.Id) newExternalId := "org.my_awesome_model@v1" @@ -1060,65 +1018,61 @@ func TestUpdateModelVersion(t *testing.T) { } updatedVersion, err := service.UpsertModelVersion(createdVersion, ®isteredModelId) - assertion.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) + suite.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) updateVersionId, _ := converter.StringToInt64(updatedVersion.Id) - assertion.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") + suite.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") - byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + byId, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *updateVersionId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") - assertion.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") - assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") - assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") - assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") - assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) + suite.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") + suite.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") + suite.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + suite.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") + suite.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + suite.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - fmt.Printf("%+v", getAllResp.Contexts) - assertion.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(2, len(getAllResp.Contexts), "there should be two contexts saved in mlmd") // update with nil name newExternalId = "org.my_awesome_model_@v1" updatedVersion.ExternalID = &newExternalId updatedVersion.Name = nil updatedVersion, err = service.UpsertModelVersion(updatedVersion, ®isteredModelId) - assertion.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) + suite.Nilf(err, "error updating new model version for %s: %v", registeredModelId, err) updateVersionId, _ = converter.StringToInt64(updatedVersion.Id) - assertion.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") + suite.Equal(*createdVersionId, *updateVersionId, "created and updated model version should have same id") - byId, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + byId, err = suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *updateVersionId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") - assertion.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") - assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") - assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") - assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") - assertion.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) + suite.Equal(*updateVersionId, *byId.Contexts[0].Id, "returned model id should match the mlmd one") + suite.Equal(fmt.Sprintf("%s:%s", registeredModelId, modelVersionName), *byId.Contexts[0].Name, "saved model name should match the provided one") + suite.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + suite.Equal(author, byId.Contexts[0].Properties["author"].GetStringValue(), "saved author property should match the provided one") + suite.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + suite.Equalf(*modelVersionTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *modelVersionTypeName) } -func TestUpdateModelVersionFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateModelVersionFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -1127,8 +1081,8 @@ func TestUpdateModelVersionFailure(t *testing.T) { } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %s", registeredModelId) - assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + suite.Nilf(err, "error creating new model version for %s", registeredModelId) + suite.NotNilf(createdVersion.Id, "created model version should not have nil Id") newExternalId := "org.my_awesome_model@v1" newScore := 0.95 @@ -1143,18 +1097,15 @@ func TestUpdateModelVersionFailure(t *testing.T) { wrongId := "9999" createdVersion.Id = &wrongId _, err = service.UpsertModelVersion(createdVersion, ®isteredModelId) - assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("no model version found for id %s", wrongId), err.Error()) + suite.NotNil(err) + suite.Equal(fmt.Sprintf("no model version found for id %s", wrongId), err.Error()) } -func TestGetModelVersionById(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelVersionById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) state := openapi.MODELVERSIONSTATE_ARCHIVED modelVersion := &openapi.ModelVersion{ @@ -1165,51 +1116,45 @@ func TestGetModelVersionById(t *testing.T) { } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) - assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + suite.NotNilf(createdVersion.Id, "created model version should not have nil Id") createdVersionId, _ := converter.StringToInt64(createdVersion.Id) getById, err := service.GetModelVersionById(*createdVersion.Id) - assertion.Nilf(err, "error getting model version with id %d", *createdVersionId) + suite.Nilf(err, "error getting model version with id %d", *createdVersionId) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdVersionId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*converter.Int64ToString(ctx.Id), *getById.Id, "returned model version id should match the mlmd context one") - assertion.Equal(*modelVersion.Name, *getById.Name, "saved model name should match the provided one") - assertion.Equal(*modelVersion.ExternalID, *getById.ExternalID, "saved external id should match the provided one") - assertion.Equal(*modelVersion.State, *getById.State, "saved model state should match the original one") - assertion.Equal(*getById.Author, author, "saved author property should match the provided one") + suite.Equal(*converter.Int64ToString(ctx.Id), *getById.Id, "returned model version id should match the mlmd context one") + suite.Equal(*modelVersion.Name, *getById.Name, "saved model name should match the provided one") + suite.Equal(*modelVersion.ExternalID, *getById.ExternalID, "saved external id should match the provided one") + suite.Equal(*modelVersion.State, *getById.State, "saved model state should match the original one") + suite.Equal(*getById.Author, author, "saved author property should match the provided one") } -func TestGetModelVersionByParamsWithNoResults(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelVersionByParamsWithNoResults() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) _, err := service.GetModelVersionByParams(of("not-present"), ®isteredModelId, nil) - assertion.NotNil(err) - assertion.Equal("no model versions found for versionName=not-present, parentResourceId=1, externalId=", err.Error()) + suite.NotNil(err) + suite.Equal("no model versions found for versionName=not-present, parentResourceId=1, externalId=", err.Error()) } -func TestGetModelVersionByParamsName(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelVersionByParamsName() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -1218,36 +1163,33 @@ func TestGetModelVersionByParamsName(t *testing.T) { } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) - assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + suite.NotNilf(createdVersion.Id, "created model version should not have nil Id") createdVersionId, _ := converter.StringToInt64(createdVersion.Id) getByName, err := service.GetModelVersionByParams(&modelVersionName, ®isteredModelId, nil) - assertion.Nilf(err, "error getting model version by name %d", *createdVersionId) + suite.Nilf(err, "error getting model version by name %d", *createdVersionId) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdVersionId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned model version id should match the mlmd context one") - assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByName.Name), *ctx.Name, "saved model name should match the provided one") - assertion.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.Properties["author"].GetStringValue(), *getByName.Author, "saved author property should match the provided one") + suite.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned model version id should match the mlmd context one") + suite.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByName.Name), *ctx.Name, "saved model name should match the provided one") + suite.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") + suite.Equal(ctx.Properties["author"].GetStringValue(), *getByName.Author, "saved author property should match the provided one") } -func TestGetModelVersionByParamsExternalId(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelVersionByParamsExternalId() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -1256,36 +1198,33 @@ func TestGetModelVersionByParamsExternalId(t *testing.T) { } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) - assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + suite.NotNilf(createdVersion.Id, "created model version should not have nil Id") createdVersionId, _ := converter.StringToInt64(createdVersion.Id) getByExternalId, err := service.GetModelVersionByParams(nil, nil, modelVersion.ExternalID) - assertion.Nilf(err, "error getting model version by external id %d", *modelVersion.ExternalID) + suite.Nilf(err, "error getting model version by external id %d", *modelVersion.ExternalID) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdVersionId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned model version id should match the mlmd context one") - assertion.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByExternalId.Name), *ctx.Name, "saved model name should match the provided one") - assertion.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.Properties["author"].GetStringValue(), *getByExternalId.Author, "saved author property should match the provided one") + suite.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned model version id should match the mlmd context one") + suite.Equal(fmt.Sprintf("%s:%s", registeredModelId, *getByExternalId.Name), *ctx.Name, "saved model name should match the provided one") + suite.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") + suite.Equal(ctx.Properties["author"].GetStringValue(), *getByExternalId.Author, "saved author property should match the provided one") } -func TestGetModelVersionByEmptyParams(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelVersionByEmptyParams() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -1294,22 +1233,19 @@ func TestGetModelVersionByEmptyParams(t *testing.T) { } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) - assertion.NotNilf(createdVersion.Id, "created model version should not have nil Id") + suite.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.NotNilf(createdVersion.Id, "created model version should not have nil Id") _, err = service.GetModelVersionByParams(nil, nil, nil) - assertion.NotNil(err) - assertion.Equal("invalid parameters call, supply either (versionName and parentResourceId), or externalId", err.Error()) + suite.NotNil(err) + suite.Equal("invalid parameters call, supply either (versionName and parentResourceId), or externalId", err.Error()) } -func TestGetModelVersions(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelVersions() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) modelVersion1 := &openapi.ModelVersion{ Name: &modelVersionName, @@ -1331,17 +1267,17 @@ func TestGetModelVersions(t *testing.T) { } createdVersion1, err := service.UpsertModelVersion(modelVersion1, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersion2, err := service.UpsertModelVersion(modelVersion2, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersion3, err := service.UpsertModelVersion(modelVersion3, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) anotherRegModelName := "AnotherModel" anotherRegModelExtId := "org.another" - anotherRegisteredModelId := registerModel(assertion, service, &anotherRegModelName, &anotherRegModelExtId) + anotherRegisteredModelId := suite.registerModel(service, &anotherRegModelName, &anotherRegModelExtId) anotherModelVersionName := "v1.0" anotherModelVersionExtId := "org.another@v1.0" @@ -1351,23 +1287,23 @@ func TestGetModelVersions(t *testing.T) { } _, err = service.UpsertModelVersion(modelVersionAnother, &anotherRegisteredModelId) - assertion.Nilf(err, "error creating new model version for %d", anotherRegisteredModelId) + suite.Nilf(err, "error creating new model version for %d", anotherRegisteredModelId) createdVersionId1, _ := converter.StringToInt64(createdVersion1.Id) createdVersionId2, _ := converter.StringToInt64(createdVersion2.Id) createdVersionId3, _ := converter.StringToInt64(createdVersion3.Id) getAll, err := service.GetModelVersions(api.ListOptions{}, nil) - assertion.Nilf(err, "error getting all model versions") - assertion.Equal(int32(4), getAll.Size, "expected four model versions across all registered models") + suite.Nilf(err, "error getting all model versions") + suite.Equal(int32(4), getAll.Size, "expected four model versions across all registered models") getAllByRegModel, err := service.GetModelVersions(api.ListOptions{}, ®isteredModelId) - assertion.Nilf(err, "error getting all model versions") - assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) + suite.Nilf(err, "error getting all model versions") + suite.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) - assertion.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[0].Id) - assertion.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[2].Id) // order by last update time, expecting last created as first orderByLastUpdate := "LAST_UPDATE_TIME" @@ -1375,43 +1311,40 @@ func TestGetModelVersions(t *testing.T) { OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, ®isteredModelId) - assertion.Nilf(err, "error getting all model versions") - assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) + suite.Nilf(err, "error getting all model versions") + suite.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) - assertion.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[2].Id) - assertion.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[0].Id) // update the second version newVersionExternalId := "updated.org:v2" createdVersion2.ExternalID = &newVersionExternalId createdVersion2, err = service.UpsertModelVersion(createdVersion2, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) - assertion.Equal(newVersionExternalId, *createdVersion2.ExternalID) + suite.Equal(newVersionExternalId, *createdVersion2.ExternalID) getAllByRegModel, err = service.GetModelVersions(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, ®isteredModelId) - assertion.Nilf(err, "error getting all model versions") - assertion.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) + suite.Nilf(err, "error getting all model versions") + suite.Equalf(int32(3), getAllByRegModel.Size, "expected three model versions for registered model %d", registeredModelId) - assertion.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[2].Id) - assertion.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[0].Id) - assertion.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdVersionId1), *getAllByRegModel.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdVersionId2), *getAllByRegModel.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[1].Id) } // MODEL ARTIFACTS -func TestCreateModelArtifact(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateModelArtifact() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ Name: &artifactName, @@ -1432,51 +1365,48 @@ func TestCreateModelArtifact(t *testing.T) { } createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) state, _ := openapi.NewArtifactStateFromValue(artifactState) - assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") - assertion.Equal(artifactName, *createdArtifact.Name) - assertion.Equal(*state, *createdArtifact.State) - assertion.Equal(artifactUri, *createdArtifact.Uri) - assertion.Equal(artifactDescription, *createdArtifact.Description) - assertion.Equal("onnx", *createdArtifact.ModelFormatName) - assertion.Equal("1", *createdArtifact.ModelFormatVersion) - assertion.Equal("aws-connection-models", *createdArtifact.StorageKey) - assertion.Equal("bucket", *createdArtifact.StoragePath) - assertion.Equal(customString, *(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) + suite.NotNil(createdArtifact.Id, "created artifact id should not be nil") + suite.Equal(artifactName, *createdArtifact.Name) + suite.Equal(*state, *createdArtifact.State) + suite.Equal(artifactUri, *createdArtifact.Uri) + suite.Equal(artifactDescription, *createdArtifact.Description) + suite.Equal("onnx", *createdArtifact.ModelFormatName) + suite.Equal("1", *createdArtifact.ModelFormatVersion) + suite.Equal("aws-connection-models", *createdArtifact.StorageKey) + suite.Equal("bucket", *createdArtifact.StoragePath) + suite.Equal(customString, *(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) - getById, err := client.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ + getById, err := suite.mlmdClient.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ ArtifactIds: []int64{*createdArtifactId}, }) - assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) - - assertion.Equal(*createdArtifactId, *getById.Artifacts[0].Id) - assertion.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) - assertion.Equal(string(*createdArtifact.State), getById.Artifacts[0].State.String()) - assertion.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) - assertion.Equal(*createdArtifact.Description, getById.Artifacts[0].Properties["description"].GetStringValue()) - assertion.Equal(*createdArtifact.ModelFormatName, getById.Artifacts[0].Properties["model_format_name"].GetStringValue()) - assertion.Equal(*createdArtifact.ModelFormatVersion, getById.Artifacts[0].Properties["model_format_version"].GetStringValue()) - assertion.Equal(*createdArtifact.StorageKey, getById.Artifacts[0].Properties["storage_key"].GetStringValue()) - assertion.Equal(*createdArtifact.StoragePath, getById.Artifacts[0].Properties["storage_path"].GetStringValue()) - assertion.Equal(*(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) + suite.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + + suite.Equal(*createdArtifactId, *getById.Artifacts[0].Id) + suite.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) + suite.Equal(string(*createdArtifact.State), getById.Artifacts[0].State.String()) + suite.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) + suite.Equal(*createdArtifact.Description, getById.Artifacts[0].Properties["description"].GetStringValue()) + suite.Equal(*createdArtifact.ModelFormatName, getById.Artifacts[0].Properties["model_format_name"].GetStringValue()) + suite.Equal(*createdArtifact.ModelFormatVersion, getById.Artifacts[0].Properties["model_format_version"].GetStringValue()) + suite.Equal(*createdArtifact.StorageKey, getById.Artifacts[0].Properties["storage_key"].GetStringValue()) + suite.Equal(*createdArtifact.StoragePath, getById.Artifacts[0].Properties["storage_path"].GetStringValue()) + suite.Equal(*(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) modelVersionIdAsInt, _ := converter.StringToInt64(&modelVersionId) - byCtx, _ := client.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ + byCtx, _ := suite.mlmdClient.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ ContextId: (*int64)(modelVersionIdAsInt), }) - assertion.Equal(1, len(byCtx.Artifacts)) - assertion.Equal(*createdArtifactId, *byCtx.Artifacts[0].Id) + suite.Equal(1, len(byCtx.Artifacts)) + suite.Equal(*createdArtifactId, *byCtx.Artifacts[0].Id) } -func TestCreateModelArtifactFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateModelArtifactFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() modelVersionId := "9998" @@ -1494,22 +1424,19 @@ func TestCreateModelArtifactFailure(t *testing.T) { } _, err := service.UpsertModelArtifact(modelArtifact, nil) - assertion.NotNil(err) - assertion.Equal("missing model version id, cannot create model artifact without model version", err.Error()) + suite.NotNil(err) + suite.Equal("missing model version id, cannot create model artifact without model version", err.Error()) _, err = service.UpsertModelArtifact(modelArtifact, &modelVersionId) - assertion.NotNil(err) - assertion.Equal("no model version found for id 9998", err.Error()) + suite.NotNil(err) + suite.Equal("no model version found for id 9998", err.Error()) } -func TestUpdateModelArtifact(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateModelArtifact() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ Name: &artifactName, @@ -1525,37 +1452,34 @@ func TestUpdateModelArtifact(t *testing.T) { } createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) newState := "MARKED_FOR_DELETION" createdArtifact.State = (*openapi.ArtifactState)(&newState) updatedArtifact, err := service.UpsertModelArtifact(createdArtifact, &modelVersionId) - assertion.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) + suite.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) updatedArtifactId, _ := converter.StringToInt64(updatedArtifact.Id) - assertion.Equal(createdArtifactId, updatedArtifactId) + suite.Equal(createdArtifactId, updatedArtifactId) - getById, err := client.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ + getById, err := suite.mlmdClient.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ ArtifactIds: []int64{*createdArtifactId}, }) - assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + suite.Nilf(err, "error getting model artifact by id %d", createdArtifactId) - assertion.Equal(*createdArtifactId, *getById.Artifacts[0].Id) - assertion.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) - assertion.Equal(string(newState), getById.Artifacts[0].State.String()) - assertion.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) - assertion.Equal(*(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) + suite.Equal(*createdArtifactId, *getById.Artifacts[0].Id) + suite.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) + suite.Equal(string(newState), getById.Artifacts[0].State.String()) + suite.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) + suite.Equal(*(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) } -func TestUpdateModelArtifactFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateModelArtifactFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ Name: &artifactName, @@ -1571,29 +1495,26 @@ func TestUpdateModelArtifactFailure(t *testing.T) { } createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for model version %s", modelVersionId) - assertion.NotNilf(createdArtifact.Id, "created model artifact should not have nil Id") + suite.Nilf(err, "error creating new model artifact for model version %s", modelVersionId) + suite.NotNilf(createdArtifact.Id, "created model artifact should not have nil Id") newState := "MARKED_FOR_DELETION" createdArtifact.State = (*openapi.ArtifactState)(&newState) updatedArtifact, err := service.UpsertModelArtifact(createdArtifact, &modelVersionId) - assertion.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) + suite.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) wrongId := "9998" updatedArtifact.Id = &wrongId _, err = service.UpsertModelArtifact(updatedArtifact, &modelVersionId) - assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("no model artifact found for id %s", wrongId), err.Error()) + suite.NotNil(err) + suite.Equal(fmt.Sprintf("no model artifact found for id %s", wrongId), err.Error()) } -func TestGetModelArtifactById(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelArtifactById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ Name: &artifactName, @@ -1609,31 +1530,28 @@ func TestGetModelArtifactById(t *testing.T) { } createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) getById, err := service.GetModelArtifactById(*createdArtifact.Id) - assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + suite.Nilf(err, "error getting model artifact by id %d", createdArtifactId) state, _ := openapi.NewArtifactStateFromValue(artifactState) - assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") - assertion.Equal(artifactName, *getById.Name) - assertion.Equal(*state, *getById.State) - assertion.Equal(artifactUri, *getById.Uri) - assertion.Equal(customString, *(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) + suite.NotNil(createdArtifact.Id, "created artifact id should not be nil") + suite.Equal(artifactName, *getById.Name) + suite.Equal(*state, *getById.State) + suite.Equal(artifactUri, *getById.Uri) + suite.Equal(customString, *(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) - assertion.Equal(*createdArtifact, *getById, "artifacts returned during creation and on get by id should be equal") + suite.Equal(*createdArtifact, *getById, "artifacts returned during creation and on get by id should be equal") } -func TestGetModelArtifactByParams(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelArtifactByParams() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ Name: &artifactName, @@ -1650,45 +1568,42 @@ func TestGetModelArtifactByParams(t *testing.T) { } createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) state, _ := openapi.NewArtifactStateFromValue(artifactState) getByName, err := service.GetModelArtifactByParams(&artifactName, &modelVersionId, nil) - assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + suite.Nilf(err, "error getting model artifact by id %d", createdArtifactId) - assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") - assertion.Equal(artifactName, *getByName.Name) - assertion.Equal(artifactExtId, *getByName.ExternalID) - assertion.Equal(*state, *getByName.State) - assertion.Equal(artifactUri, *getByName.Uri) - assertion.Equal(customString, *(*getByName.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) + suite.NotNil(createdArtifact.Id, "created artifact id should not be nil") + suite.Equal(artifactName, *getByName.Name) + suite.Equal(artifactExtId, *getByName.ExternalID) + suite.Equal(*state, *getByName.State) + suite.Equal(artifactUri, *getByName.Uri) + suite.Equal(customString, *(*getByName.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) - assertion.Equal(*createdArtifact, *getByName, "artifacts returned during creation and on get by name should be equal") + suite.Equal(*createdArtifact, *getByName, "artifacts returned during creation and on get by name should be equal") getByExtId, err := service.GetModelArtifactByParams(nil, nil, &artifactExtId) - assertion.Nilf(err, "error getting model artifact by id %d", createdArtifactId) + suite.Nilf(err, "error getting model artifact by id %d", createdArtifactId) - assertion.NotNil(createdArtifact.Id, "created artifact id should not be nil") - assertion.Equal(artifactName, *getByExtId.Name) - assertion.Equal(artifactExtId, *getByExtId.ExternalID) - assertion.Equal(*state, *getByExtId.State) - assertion.Equal(artifactUri, *getByExtId.Uri) - assertion.Equal(customString, *(*getByExtId.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) + suite.NotNil(createdArtifact.Id, "created artifact id should not be nil") + suite.Equal(artifactName, *getByExtId.Name) + suite.Equal(artifactExtId, *getByExtId.ExternalID) + suite.Equal(*state, *getByExtId.State) + suite.Equal(artifactUri, *getByExtId.Uri) + suite.Equal(customString, *(*getByExtId.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) - assertion.Equal(*createdArtifact, *getByExtId, "artifacts returned during creation and on get by ext id should be equal") + suite.Equal(*createdArtifact, *getByExtId, "artifacts returned during creation and on get by ext id should be equal") } -func TestGetModelArtifactByEmptyParams(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelArtifactByEmptyParams() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) modelArtifact := &openapi.ModelArtifact{ Name: &artifactName, @@ -1705,35 +1620,29 @@ func TestGetModelArtifactByEmptyParams(t *testing.T) { } _, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) _, err = service.GetModelArtifactByParams(nil, nil, nil) - assertion.NotNil(err) - assertion.Equal("invalid parameters call, supply either (artifactName and parentResourceId), or externalId", err.Error()) + suite.NotNil(err) + suite.Equal("invalid parameters call, supply either (artifactName and parentResourceId), or externalId", err.Error()) } -func TestGetModelArtifactByParamsWithNoResults(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelArtifactByParamsWithNoResults() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) _, err := service.GetModelArtifactByParams(of("not-present"), &modelVersionId, nil) - assertion.NotNil(err) - assertion.Equal("no model artifacts found for artifactName=not-present, parentResourceId=2, externalId=", err.Error()) + suite.NotNil(err) + suite.Equal("no model artifacts found for artifactName=not-present, parentResourceId=2, externalId=", err.Error()) } -func TestGetModelArtifacts(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelArtifacts() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - modelVersionId := registerModelVersion(assertion, service, nil, nil, nil, nil) + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) modelArtifact1 := &openapi.ModelArtifact{ Name: &artifactName, @@ -1784,45 +1693,42 @@ func TestGetModelArtifacts(t *testing.T) { } createdArtifact1, err := service.UpsertModelArtifact(modelArtifact1, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) createdArtifact2, err := service.UpsertModelArtifact(modelArtifact2, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) createdArtifact3, err := service.UpsertModelArtifact(modelArtifact3, &modelVersionId) - assertion.Nilf(err, "error creating new model artifact for %d", modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) createdArtifactId1, _ := converter.StringToInt64(createdArtifact1.Id) createdArtifactId2, _ := converter.StringToInt64(createdArtifact2.Id) createdArtifactId3, _ := converter.StringToInt64(createdArtifact3.Id) getAll, err := service.GetModelArtifacts(api.ListOptions{}, nil) - assertion.Nilf(err, "error getting all model artifacts") - assertion.Equalf(int32(3), getAll.Size, "expected three model artifacts") + suite.Nilf(err, "error getting all model artifacts") + suite.Equalf(int32(3), getAll.Size, "expected three model artifacts") - assertion.Equal(*converter.Int64ToString(createdArtifactId1), *getAll.Items[0].Id) - assertion.Equal(*converter.Int64ToString(createdArtifactId2), *getAll.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdArtifactId3), *getAll.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdArtifactId1), *getAll.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdArtifactId2), *getAll.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdArtifactId3), *getAll.Items[2].Id) orderByLastUpdate := "LAST_UPDATE_TIME" getAllByModelVersion, err := service.GetModelArtifacts(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &modelVersionId) - assertion.Nilf(err, "error getting all model artifacts for %d", modelVersionId) - assertion.Equalf(int32(3), getAllByModelVersion.Size, "expected three model artifacts for model version %d", modelVersionId) + suite.Nilf(err, "error getting all model artifacts for %d", modelVersionId) + suite.Equalf(int32(3), getAllByModelVersion.Size, "expected three model artifacts for model version %d", modelVersionId) - assertion.Equal(*converter.Int64ToString(createdArtifactId1), *getAllByModelVersion.Items[2].Id) - assertion.Equal(*converter.Int64ToString(createdArtifactId2), *getAllByModelVersion.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdArtifactId3), *getAllByModelVersion.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdArtifactId1), *getAllByModelVersion.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdArtifactId2), *getAllByModelVersion.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdArtifactId3), *getAllByModelVersion.Items[0].Id) } // SERVING ENVIRONMENT -func TestCreateServingEnvironment(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateServingEnvironment() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new ServingEnvironment eut := &openapi.ServingEnvironment{ @@ -1842,34 +1748,31 @@ func TestCreateServingEnvironment(t *testing.T) { createdEntity, err := service.UpsertServingEnvironment(eut) // checks - assertion.Nilf(err, "error creating uut: %v", err) - assertion.NotNilf(createdEntity.Id, "created uut should not have nil Id") + suite.Nilf(err, "error creating uut: %v", err) + suite.NotNilf(createdEntity.Id, "created uut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{*createdEntityId}, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] ctxId := converter.Int64ToString(ctx.Id) - assertion.Equal(*createdEntity.Id, *ctxId, "returned id should match the mlmd one") - assertion.Equal(entityName, *ctx.Name, "saved name should match the provided one") - assertion.Equal(entityExternalId, *ctx.ExternalId, "saved external id should match the provided one") - assertion.Equal(entityDescription, ctx.Properties["description"].GetStringValue(), "saved description should match the provided one") - assertion.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + suite.Equal(*createdEntity.Id, *ctxId, "returned id should match the mlmd one") + suite.Equal(entityName, *ctx.Name, "saved name should match the provided one") + suite.Equal(entityExternalId, *ctx.ExternalId, "saved external id should match the provided one") + suite.Equal(entityDescription, ctx.Properties["description"].GetStringValue(), "saved description should match the provided one") + suite.Equal(owner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") } -func TestUpdateServingEnvironment(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateServingEnvironment() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new ServingEnvironment eut := &openapi.ServingEnvironment{ @@ -1888,14 +1791,14 @@ func TestUpdateServingEnvironment(t *testing.T) { createdEntity, err := service.UpsertServingEnvironment(eut) // checks - assertion.Nilf(err, "error creating uut: %v", err) - assertion.NotNilf(createdEntity.Id, "created uut should not have nil Id") + suite.Nilf(err, "error creating uut: %v", err) + suite.NotNilf(createdEntity.Id, "created uut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) // checks created entity matches original one except for Id - assertion.Equal(*eut.Name, *createdEntity.Name, "returned entity should match the original one") - assertion.Equal(*eut.ExternalID, *createdEntity.ExternalID, "returned entity external id should match the original one") - assertion.Equal(*eut.CustomProperties, *createdEntity.CustomProperties, "returned entity custom props should match the original one") + suite.Equal(*eut.Name, *createdEntity.Name, "returned entity should match the original one") + suite.Equal(*eut.ExternalID, *createdEntity.ExternalID, "returned entity external id should match the original one") + suite.Equal(*eut.CustomProperties, *createdEntity.CustomProperties, "returned entity custom props should match the original one") // update existing entity newExternalId := "newExternalId" @@ -1910,56 +1813,53 @@ func TestUpdateServingEnvironment(t *testing.T) { // update the entity createdEntity, err = service.UpsertServingEnvironment(createdEntity) - assertion.Nilf(err, "error creating uut: %v", err) + suite.Nilf(err, "error creating uut: %v", err) // still one expected MLMD type - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{*createdEntityId}, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] ctxId := converter.Int64ToString(ctx.Id) - assertion.Equal(*createdEntity.Id, *ctxId, "returned entity id should match the mlmd one") - assertion.Equal(entityName, *ctx.Name, "saved entity name should match the provided one") - assertion.Equal(newExternalId, *ctx.ExternalId, "saved external id should match the provided one") - assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + suite.Equal(*createdEntity.Id, *ctxId, "returned entity id should match the mlmd one") + suite.Equal(entityName, *ctx.Name, "saved entity name should match the provided one") + suite.Equal(newExternalId, *ctx.ExternalId, "saved external id should match the provided one") + suite.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") // update the entity under test, keeping nil name newExternalId = "newNewExternalId" createdEntity.ExternalID = &newExternalId createdEntity.Name = nil createdEntity, err = service.UpsertServingEnvironment(createdEntity) - assertion.Nilf(err, "error creating entity: %v", err) + suite.Nilf(err, "error creating entity: %v", err) // still one registered entity - getAllResp, err = client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") + getAllResp, err = suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(1, len(getAllResp.Contexts), "there should be just one context saved in mlmd") - ctxById, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err = suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{*createdEntityId}, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) ctx = ctxById.Contexts[0] ctxId = converter.Int64ToString(ctx.Id) - assertion.Equal(*createdEntity.Id, *ctxId, "returned entity id should match the mlmd one") - assertion.Equal(entityName, *ctx.Name, "saved entity name should match the provided one") - assertion.Equal(newExternalId, *ctx.ExternalId, "saved external id should match the provided one") - assertion.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") + suite.Equal(*createdEntity.Id, *ctxId, "returned entity id should match the mlmd one") + suite.Equal(entityName, *ctx.Name, "saved entity name should match the provided one") + suite.Equal(newExternalId, *ctx.ExternalId, "saved external id should match the provided one") + suite.Equal(newOwner, ctx.CustomProperties["owner"].GetStringValue(), "saved owner custom property should match the provided one") } -func TestGetServingEnvironmentById(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new entity eut := &openapi.ServingEnvironment{ @@ -1978,35 +1878,29 @@ func TestGetServingEnvironmentById(t *testing.T) { createdEntity, err := service.UpsertServingEnvironment(eut) // checks - assertion.Nilf(err, "error creating eut: %v", err) + suite.Nilf(err, "error creating eut: %v", err) getEntityById, err := service.GetServingEnvironmentById(*createdEntity.Id) - assertion.Nilf(err, "error getting eut by id %s: %v", *createdEntity.Id, err) + suite.Nilf(err, "error getting eut by id %s: %v", *createdEntity.Id, err) // checks created entity matches original one except for Id - assertion.Equal(*eut.Name, *getEntityById.Name, "saved name should match the original one") - assertion.Equal(*eut.ExternalID, *getEntityById.ExternalID, "saved external id should match the original one") - assertion.Equal(*eut.CustomProperties, *getEntityById.CustomProperties, "saved custom props should match the original one") + suite.Equal(*eut.Name, *getEntityById.Name, "saved name should match the original one") + suite.Equal(*eut.ExternalID, *getEntityById.ExternalID, "saved external id should match the original one") + suite.Equal(*eut.CustomProperties, *getEntityById.CustomProperties, "saved custom props should match the original one") } -func TestGetServingEnvironmentByParamsWithNoResults(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentByParamsWithNoResults() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() _, err := service.GetServingEnvironmentByParams(of("not-present"), nil) - assertion.NotNil(err) - assertion.Equal("no serving environments found for name=not-present, externalId=", err.Error()) + suite.NotNil(err) + suite.Equal("no serving environments found for name=not-present, externalId=", err.Error()) } -func TestGetServingEnvironmentByParamsName(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentByParamsName() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new ServingEnvironment eut := &openapi.ServingEnvironment{ @@ -2015,20 +1909,17 @@ func TestGetServingEnvironmentByParamsName(t *testing.T) { } createdEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) byName, err := service.GetServingEnvironmentByParams(&entityName, nil) - assertion.Nilf(err, "error getting ServingEnvironment by name: %v", err) + suite.Nilf(err, "error getting ServingEnvironment by name: %v", err) - assertion.Equalf(*createdEntity.Id, *byName.Id, "the returned entity id should match the retrieved by name") + suite.Equalf(*createdEntity.Id, *byName.Id, "the returned entity id should match the retrieved by name") } -func TestGetServingEnvironmentByParamsExternalId(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentByParamsExternalId() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new ServingEnvironment eut := &openapi.ServingEnvironment{ @@ -2037,20 +1928,17 @@ func TestGetServingEnvironmentByParamsExternalId(t *testing.T) { } createdEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) byName, err := service.GetServingEnvironmentByParams(nil, &entityExternalId) - assertion.Nilf(err, "error getting ServingEnvironment by external id: %v", err) + suite.Nilf(err, "error getting ServingEnvironment by external id: %v", err) - assertion.Equalf(*createdEntity.Id, *byName.Id, "the returned entity id should match the retrieved by name") + suite.Equalf(*createdEntity.Id, *byName.Id, "the returned entity id should match the retrieved by name") } -func TestGetServingEnvironmentByEmptyParams(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentByEmptyParams() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() // register a new ServingEnvironment eut := &openapi.ServingEnvironment{ @@ -2059,19 +1947,16 @@ func TestGetServingEnvironmentByEmptyParams(t *testing.T) { } _, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) _, err = service.GetServingEnvironmentByParams(nil, nil) - assertion.NotNil(err) - assertion.Equal("invalid parameters call, supply either name or externalId", err.Error()) + suite.NotNil(err) + suite.Equal("invalid parameters call, supply either name or externalId", err.Error()) } -func TestGetServingEnvironmentsOrderedById(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentsOrderedById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() orderBy := "ID" @@ -2082,51 +1967,48 @@ func TestGetServingEnvironmentsOrderedById(t *testing.T) { } _, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) newName := "Pricingentity2" newExternalId := "myExternalId2" eut.Name = &newName eut.ExternalID = &newExternalId _, err = service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) newName = "Pricingentity3" newExternalId = "myExternalId3" eut.Name = &newName eut.ExternalID = &newExternalId _, err = service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) orderedById, err := service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) - assertion.Nilf(err, "error getting ServingEnvironment: %v", err) + suite.Nilf(err, "error getting ServingEnvironment: %v", err) - assertion.Equal(3, int(orderedById.Size)) + suite.Equal(3, int(orderedById.Size)) for i := 0; i < int(orderedById.Size)-1; i++ { - assertion.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + suite.Less(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) } orderedById, err = service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) - assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + suite.Nilf(err, "error getting ServingEnvironments: %v", err) - assertion.Equal(3, int(orderedById.Size)) + suite.Equal(3, int(orderedById.Size)) for i := 0; i < int(orderedById.Size)-1; i++ { - assertion.Greater(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) + suite.Greater(*orderedById.Items[i].Id, *orderedById.Items[i+1].Id) } } -func TestGetServingEnvironmentsOrderedByLastUpdate(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentsOrderedByLastUpdate() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() orderBy := "LAST_UPDATE_TIME" @@ -2137,56 +2019,53 @@ func TestGetServingEnvironmentsOrderedByLastUpdate(t *testing.T) { } firstEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) newName := "Pricingentity2" newExternalId := "myExternalId2" eut.Name = &newName eut.ExternalID = &newExternalId secondEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) newName = "Pricingentity3" newExternalId = "myExternalId3" eut.Name = &newName eut.ExternalID = &newExternalId thirdEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) // update second entity secondEntity.ExternalID = nil _, err = service.UpsertServingEnvironment(secondEntity) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) orderedById, err := service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &ascOrderDirection, }) - assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + suite.Nilf(err, "error getting ServingEnvironments: %v", err) - assertion.Equal(3, int(orderedById.Size)) - assertion.Equal(*firstEntity.Id, *orderedById.Items[0].Id) - assertion.Equal(*thirdEntity.Id, *orderedById.Items[1].Id) - assertion.Equal(*secondEntity.Id, *orderedById.Items[2].Id) + suite.Equal(3, int(orderedById.Size)) + suite.Equal(*firstEntity.Id, *orderedById.Items[0].Id) + suite.Equal(*thirdEntity.Id, *orderedById.Items[1].Id) + suite.Equal(*secondEntity.Id, *orderedById.Items[2].Id) orderedById, err = service.GetServingEnvironments(api.ListOptions{ OrderBy: &orderBy, SortOrder: &descOrderDirection, }) - assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + suite.Nilf(err, "error getting ServingEnvironments: %v", err) - assertion.Equal(3, int(orderedById.Size)) - assertion.Equal(*secondEntity.Id, *orderedById.Items[0].Id) - assertion.Equal(*thirdEntity.Id, *orderedById.Items[1].Id) - assertion.Equal(*firstEntity.Id, *orderedById.Items[2].Id) + suite.Equal(3, int(orderedById.Size)) + suite.Equal(*secondEntity.Id, *orderedById.Items[0].Id) + suite.Equal(*thirdEntity.Id, *orderedById.Items[1].Id) + suite.Equal(*firstEntity.Id, *orderedById.Items[2].Id) } -func TestGetServingEnvironmentsWithPageSize(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServingEnvironmentsWithPageSize() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() pageSize := int32(1) pageSize2 := int32(2) @@ -2200,54 +2079,51 @@ func TestGetServingEnvironmentsWithPageSize(t *testing.T) { } firstEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating registered entity: %v", err) + suite.Nilf(err, "error creating registered entity: %v", err) newName := "Pricingentity2" newExternalId := "myExternalId2" eut.Name = &newName eut.ExternalID = &newExternalId secondEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) newName = "Pricingentity3" newExternalId = "myExternalId3" eut.Name = &newName eut.ExternalID = &newExternalId thirdEntity, err := service.UpsertServingEnvironment(eut) - assertion.Nilf(err, "error creating ServingEnvironment: %v", err) + suite.Nilf(err, "error creating ServingEnvironment: %v", err) truncatedList, err := service.GetServingEnvironments(api.ListOptions{ PageSize: &pageSize, }) - assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + suite.Nilf(err, "error getting ServingEnvironments: %v", err) - assertion.Equal(1, int(truncatedList.Size)) - assertion.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") - assertion.Equal(*firstEntity.Id, *truncatedList.Items[0].Id) + suite.Equal(1, int(truncatedList.Size)) + suite.NotEqual("", truncatedList.NextPageToken, "next page token should not be empty") + suite.Equal(*firstEntity.Id, *truncatedList.Items[0].Id) truncatedList, err = service.GetServingEnvironments(api.ListOptions{ PageSize: &pageSize2, NextPageToken: &truncatedList.NextPageToken, }) - assertion.Nilf(err, "error getting ServingEnvironments: %v", err) + suite.Nilf(err, "error getting ServingEnvironments: %v", err) - assertion.Equal(2, int(truncatedList.Size)) - assertion.Equal("", truncatedList.NextPageToken, "next page token should be empty as list item returned") - assertion.Equal(*secondEntity.Id, *truncatedList.Items[0].Id) - assertion.Equal(*thirdEntity.Id, *truncatedList.Items[1].Id) + suite.Equal(2, int(truncatedList.Size)) + suite.Equal("", truncatedList.NextPageToken, "next page token should be empty as list item returned") + suite.Equal(*secondEntity.Id, *truncatedList.Items[0].Id) + suite.Equal(*thirdEntity.Id, *truncatedList.Items[1].Id) } // INFERENCE SERVICE -func TestCreateInferenceService(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateInferenceService() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) runtime := "model-server" state := openapi.INFERENCESERVICESTATE_DEPLOYED @@ -2269,40 +2145,37 @@ func TestCreateInferenceService(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %s: %v", parentResourceId, err) + suite.Nilf(err, "error creating new eut for %s: %v", parentResourceId, err) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) - byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + byId, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdEntityId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - assertion.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Equal(1, len(byId.Contexts), "there should be just one context saved in mlmd") - assertion.Equal(*createdEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") - assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, entityName), *byId.Contexts[0].Name, "saved name should match the provided one") - assertion.Equal(entityExternalId2, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") - assertion.Equal(entityDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") - assertion.Equal(runtime, byId.Contexts[0].Properties["runtime"].GetStringValue(), "saved runtime should match the provided one") - assertion.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") - assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) + suite.Equal(*createdEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") + suite.Equal(fmt.Sprintf("%s:%s", parentResourceId, entityName), *byId.Contexts[0].Name, "saved name should match the provided one") + suite.Equal(entityExternalId2, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + suite.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") + suite.Equal(entityDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") + suite.Equal(runtime, byId.Contexts[0].Properties["runtime"].GetStringValue(), "saved runtime should match the provided one") + suite.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") + suite.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(3, len(getAllResp.Contexts), "there should be 3 contexts (RegisteredModel, ServingEnvironment, InferenceService) saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(3, len(getAllResp.Contexts), "there should be 3 contexts (RegisteredModel, ServingEnvironment, InferenceService) saved in mlmd") } -func TestCreateInferenceServiceFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateInferenceServiceFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() eut := &openapi.InferenceService{ Name: &entityName, @@ -2319,26 +2192,23 @@ func TestCreateInferenceServiceFailure(t *testing.T) { } _, err := service.UpsertInferenceService(eut) - assertion.NotNil(err) - assertion.Equal("no serving environment found for id 9999", err.Error()) + suite.NotNil(err) + suite.Equal("no serving environment found for id 9999", err.Error()) - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) eut.ServingEnvironmentId = parentResourceId _, err = service.UpsertInferenceService(eut) - assertion.NotNil(err) - assertion.Equal("no registered model found for id 9998", err.Error()) + suite.NotNil(err) + suite.Equal("no registered model found for id 9998", err.Error()) } -func TestUpdateInferenceService(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateInferenceService() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) eut := &openapi.InferenceService{ Name: &entityName, @@ -2356,9 +2226,9 @@ func TestUpdateInferenceService(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) @@ -2373,73 +2243,70 @@ func TestUpdateInferenceService(t *testing.T) { } updatedEntity, err := service.UpsertInferenceService(createdEntity) - assertion.Nilf(err, "error updating new entity for %s: %v", registeredModelId, err) + suite.Nilf(err, "error updating new entity for %s: %v", registeredModelId, err) updateEntityId, _ := converter.StringToInt64(updatedEntity.Id) - assertion.Equal(*createdEntityId, *updateEntityId, "created and updated should have same id") + suite.Equal(*createdEntityId, *updateEntityId, "created and updated should have same id") - byId, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + byId, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *updateEntityId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - assertion.Equal(1, len(byId.Contexts), "there should be 1 context saved in mlmd by id") + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Equal(1, len(byId.Contexts), "there should be 1 context saved in mlmd by id") - assertion.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") - assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") - assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") - assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") - assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) + suite.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") + suite.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") + suite.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + suite.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") + suite.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + suite.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) - getAllResp, err := client.GetContexts(context.Background(), &proto.GetContextsRequest{}) - assertion.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) - assertion.Equal(3, len(getAllResp.Contexts), "there should be 3 contexts saved in mlmd") + getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) + suite.Nilf(err, "error retrieving all contexts, not related to the test itself: %v", err) + suite.Equal(3, len(getAllResp.Contexts), "there should be 3 contexts saved in mlmd") // update with nil name newExternalId = "org.my_awesome_entity_@v1" updatedEntity.ExternalID = &newExternalId updatedEntity.Name = nil updatedEntity, err = service.UpsertInferenceService(updatedEntity) - assertion.Nilf(err, "error updating new model version for %s: %v", updateEntityId, err) + suite.Nilf(err, "error updating new model version for %s: %v", updateEntityId, err) updateEntityId, _ = converter.StringToInt64(updatedEntity.Id) - assertion.Equal(*createdEntityId, *updateEntityId, "created and updated should have same id") + suite.Equal(*createdEntityId, *updateEntityId, "created and updated should have same id") - byId, err = client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + byId, err = suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *updateEntityId, }, }) - assertion.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) - assertion.Equal(1, len(byId.Contexts), "there should be 1 context saved in mlmd by id") + suite.Nilf(err, "error retrieving context by type and name, not related to the test itself: %v", err) + suite.Equal(1, len(byId.Contexts), "there should be 1 context saved in mlmd by id") - assertion.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") - assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") - assertion.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") - assertion.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") - assertion.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") - assertion.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) + suite.Equal(*updateEntityId, *byId.Contexts[0].Id, "returned id should match the mlmd one") + suite.Equal(fmt.Sprintf("%s:%s", parentResourceId, *eut.Name), *byId.Contexts[0].Name, "saved name should match the provided one") + suite.Equal(newExternalId, *byId.Contexts[0].ExternalId, "saved external id should match the provided one") + suite.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") + suite.Equal(newScore, byId.Contexts[0].CustomProperties["score"].GetDoubleValue(), "saved score custom property should match the provided one") + suite.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) // update with empty registeredModelId newExternalId = "org.my_awesome_entity_@v1" prevRegModelId := updatedEntity.RegisteredModelId updatedEntity.RegisteredModelId = "" updatedEntity, err = service.UpsertInferenceService(updatedEntity) - assertion.Nil(err) - assertion.Equal(prevRegModelId, updatedEntity.RegisteredModelId) + suite.Nil(err) + suite.Equal(prevRegModelId, updatedEntity.RegisteredModelId) } -func TestUpdateInferenceServiceFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateInferenceServiceFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) eut := &openapi.InferenceService{ Name: &entityName, @@ -2457,9 +2324,9 @@ func TestUpdateInferenceServiceFailure(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") newExternalId := "org.my_awesome_entity@v1" newScore := 0.95 @@ -2474,19 +2341,16 @@ func TestUpdateInferenceServiceFailure(t *testing.T) { wrongId := "9999" createdEntity.Id = &wrongId _, err = service.UpsertInferenceService(createdEntity) - assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("no InferenceService found for id %s", wrongId), err.Error()) + suite.NotNil(err) + suite.Equal(fmt.Sprintf("no InferenceService found for id %s", wrongId), err.Error()) } -func TestGetInferenceServiceById(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetInferenceServiceById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) state := openapi.INFERENCESERVICESTATE_UNDEPLOYED eut := &openapi.InferenceService{ @@ -2506,38 +2370,35 @@ func TestGetInferenceServiceById(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getById, err := service.GetInferenceServiceById(*createdEntity.Id) - assertion.Nilf(err, "error getting model version with id %d", *createdEntityId) + suite.Nilf(err, "error getting model version with id %d", *createdEntityId) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdEntityId, }, }) - assertion.Nilf(err, "error retrieving context, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*getById.Id, *converter.Int64ToString(ctx.Id), "returned id should match the mlmd context one") - assertion.Equal(*eut.Name, *getById.Name, "saved name should match the provided one") - assertion.Equal(*eut.ExternalID, *getById.ExternalID, "saved external id should match the provided one") - assertion.Equal(*eut.State, *getById.State, "saved state should match the provided one") - assertion.Equal(*(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, customString, "saved custom_string_prop custom property should match the provided one") + suite.Equal(*getById.Id, *converter.Int64ToString(ctx.Id), "returned id should match the mlmd context one") + suite.Equal(*eut.Name, *getById.Name, "saved name should match the provided one") + suite.Equal(*eut.ExternalID, *getById.ExternalID, "saved external id should match the provided one") + suite.Equal(*eut.State, *getById.State, "saved state should match the provided one") + suite.Equal(*(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, customString, "saved custom_string_prop custom property should match the provided one") } -func TestGetRegisteredModelByInferenceServiceId(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetRegisteredModelByInferenceServiceId() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) eut := &openapi.InferenceService{ Name: &entityName, @@ -2554,36 +2415,33 @@ func TestGetRegisteredModelByInferenceServiceId(t *testing.T) { }, } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getRM, err := service.GetRegisteredModelByInferenceService(*createdEntity.Id) - assertion.Nilf(err, "error getting using id %d", *createdEntityId) + suite.Nilf(err, "error getting using id %d", *createdEntityId) - assertion.Equal(registeredModelId, *getRM.Id, "returned id should match the original registeredModelId") + suite.Equal(registeredModelId, *getRM.Id, "returned id should match the original registeredModelId") } -func TestGetModelVersionByInferenceServiceId(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetModelVersionByInferenceServiceId() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) modelVersion1Name := "v1" modelVersion1 := &openapi.ModelVersion{Name: &modelVersion1Name, Description: &modelVersionDescription} createdVersion1, err := service.UpsertModelVersion(modelVersion1, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersion1Id := *createdVersion1.Id modelVersion2Name := "v2" modelVersion2 := &openapi.ModelVersion{Name: &modelVersion2Name, Description: &modelVersionDescription} createdVersion2, err := service.UpsertModelVersion(modelVersion2, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersion2Id := *createdVersion2.Id // end of data preparation @@ -2603,46 +2461,40 @@ func TestGetModelVersionByInferenceServiceId(t *testing.T) { }, } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getVModel, err := service.GetModelVersionByInferenceService(*createdEntity.Id) - assertion.Nilf(err, "error getting using id %d", *createdEntityId) - assertion.Equal(createdVersion2Id, *getVModel.Id, "returned id shall be the latest ModelVersion by creation order") + suite.Nilf(err, "error getting using id %d", *createdEntityId) + suite.Equal(createdVersion2Id, *getVModel.Id, "returned id shall be the latest ModelVersion by creation order") // here we used the returned entity (so ID is populated), and we update to specify the "ID of the ModelVersion to serve" createdEntity.ModelVersionId = &createdVersion1Id _, err = service.UpsertInferenceService(createdEntity) - assertion.Nilf(err, "error updating eut for %v", parentResourceId) + suite.Nilf(err, "error updating eut for %v", parentResourceId) getVModel, err = service.GetModelVersionByInferenceService(*createdEntity.Id) - assertion.Nilf(err, "error getting using id %d", *createdEntityId) - assertion.Equal(createdVersion1Id, *getVModel.Id, "returned id shall be the specified one") + suite.Nilf(err, "error getting using id %d", *createdEntityId) + suite.Equal(createdVersion1Id, *getVModel.Id, "returned id shall be the specified one") } -func TestGetInferenceServiceByParamsWithNoResults(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetInferenceServiceByParamsWithNoResults() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) _, err := service.GetInferenceServiceByParams(of("not-present"), &parentResourceId, nil) - assertion.NotNil(err) - assertion.Equal("no inference services found for name=not-present, parentResourceId=1, externalId=", err.Error()) + suite.NotNil(err) + suite.Equal("no inference services found for name=not-present, parentResourceId=1, externalId=", err.Error()) } -func TestGetInferenceServiceByParamsName(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetInferenceServiceByParamsName() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) eut := &openapi.InferenceService{ Name: &entityName, @@ -2660,37 +2512,34 @@ func TestGetInferenceServiceByParamsName(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getByName, err := service.GetInferenceServiceByParams(&entityName, &parentResourceId, nil) - assertion.Nilf(err, "error getting model version by name %d", *createdEntityId) + suite.Nilf(err, "error getting model version by name %d", *createdEntityId) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdEntityId, }, }) - assertion.Nilf(err, "error retrieving context, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned id should match the mlmd context one") - assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByName.Name), *ctx.Name, "saved name should match the provided one") - assertion.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.CustomProperties["custom_string_prop"].GetStringValue(), *(*getByName.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, "saved custom_string_prop custom property should match the provided one") + suite.Equal(*converter.Int64ToString(ctx.Id), *getByName.Id, "returned id should match the mlmd context one") + suite.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByName.Name), *ctx.Name, "saved name should match the provided one") + suite.Equal(*ctx.ExternalId, *getByName.ExternalID, "saved external id should match the provided one") + suite.Equal(ctx.CustomProperties["custom_string_prop"].GetStringValue(), *(*getByName.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, "saved custom_string_prop custom property should match the provided one") } -func TestGetInfernenceServiceByParamsExternalId(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetInfernenceServiceByParamsExternalId() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) eut := &openapi.InferenceService{ Name: &entityName, @@ -2708,37 +2557,34 @@ func TestGetInfernenceServiceByParamsExternalId(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getByExternalId, err := service.GetInferenceServiceByParams(nil, nil, eut.ExternalID) - assertion.Nilf(err, "error getting by external id %d", *eut.ExternalID) + suite.Nilf(err, "error getting by external id %d", *eut.ExternalID) - ctxById, err := client.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ + ctxById, err := suite.mlmdClient.GetContextsByID(context.Background(), &proto.GetContextsByIDRequest{ ContextIds: []int64{ *createdEntityId, }, }) - assertion.Nilf(err, "error retrieving context, not related to the test itself: %v", err) + suite.Nilf(err, "error retrieving context, not related to the test itself: %v", err) ctx := ctxById.Contexts[0] - assertion.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned id should match the mlmd context one") - assertion.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByExternalId.Name), *ctx.Name, "saved name should match the provided one") - assertion.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") - assertion.Equal(ctx.CustomProperties["custom_string_prop"].GetStringValue(), *(*getByExternalId.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, "saved custom_string_prop custom property should match the provided one") + suite.Equal(*converter.Int64ToString(ctx.Id), *getByExternalId.Id, "returned id should match the mlmd context one") + suite.Equal(fmt.Sprintf("%s:%s", parentResourceId, *getByExternalId.Name), *ctx.Name, "saved name should match the provided one") + suite.Equal(*ctx.ExternalId, *getByExternalId.ExternalID, "saved external id should match the provided one") + suite.Equal(ctx.CustomProperties["custom_string_prop"].GetStringValue(), *(*getByExternalId.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, "saved custom_string_prop custom property should match the provided one") } -func TestGetInferenceServiceByEmptyParams(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetInferenceServiceByEmptyParams() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) eut := &openapi.InferenceService{ Name: &entityName, @@ -2756,24 +2602,21 @@ func TestGetInferenceServiceByEmptyParams(t *testing.T) { } createdEntity, err := service.UpsertInferenceService(eut) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) - assertion.NotNilf(createdEntity.Id, "created eut should not have nil Id") + suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") _, err = service.GetInferenceServiceByParams(nil, nil, nil) - assertion.NotNil(err) - assertion.Equal("invalid parameters call, supply either (name and parentResourceId), or externalId", err.Error()) + suite.NotNil(err) + suite.Equal("invalid parameters call, supply either (name and parentResourceId), or externalId", err.Error()) } -func TestGetInferenceServices(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetInferenceServices() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - parentResourceId := registerServingEnvironment(assertion, service, nil, nil) - registeredModelId := registerModel(assertion, service, nil, nil) + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) eut1 := &openapi.InferenceService{ Name: &entityName, @@ -2801,17 +2644,17 @@ func TestGetInferenceServices(t *testing.T) { } createdEntity1, err := service.UpsertInferenceService(eut1) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) createdEntity2, err := service.UpsertInferenceService(eut2) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) createdEntity3, err := service.UpsertInferenceService(eut3) - assertion.Nilf(err, "error creating new eut for %v", parentResourceId) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) anotherParentResourceName := "AnotherModel" anotherParentResourceExtId := "org.another" - anotherParentResourceId := registerServingEnvironment(assertion, service, &anotherParentResourceName, &anotherParentResourceExtId) + anotherParentResourceId := suite.registerServingEnvironment(service, &anotherParentResourceName, &anotherParentResourceExtId) anotherName := "v1.0" anotherExtId := "org.another@v1.0" @@ -2823,23 +2666,23 @@ func TestGetInferenceServices(t *testing.T) { } _, err = service.UpsertInferenceService(eutAnother) - assertion.Nilf(err, "error creating new model version for %d", anotherParentResourceId) + suite.Nilf(err, "error creating new model version for %d", anotherParentResourceId) createdId1, _ := converter.StringToInt64(createdEntity1.Id) createdId2, _ := converter.StringToInt64(createdEntity2.Id) createdId3, _ := converter.StringToInt64(createdEntity3.Id) getAll, err := service.GetInferenceServices(api.ListOptions{}, nil) - assertion.Nilf(err, "error getting all") - assertion.Equal(int32(4), getAll.Size, "expected 4 across all parent resources") + suite.Nilf(err, "error getting all") + suite.Equal(int32(4), getAll.Size, "expected 4 across all parent resources") getAllByParentResource, err := service.GetInferenceServices(api.ListOptions{}, &parentResourceId) - assertion.Nilf(err, "error getting all") - assertion.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) + suite.Nilf(err, "error getting all") + suite.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) - assertion.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[0].Id) - assertion.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[2].Id) // order by last update time, expecting last created as first orderByLastUpdate := "LAST_UPDATE_TIME" @@ -2847,44 +2690,41 @@ func TestGetInferenceServices(t *testing.T) { OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &parentResourceId) - assertion.Nilf(err, "error getting all") - assertion.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) + suite.Nilf(err, "error getting all") + suite.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) - assertion.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[2].Id) - assertion.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[0].Id) // update the second entity newExternalId := "updated.org:v2" createdEntity2.ExternalID = &newExternalId createdEntity2, err = service.UpsertInferenceService(createdEntity2) - assertion.Nilf(err, "error creating new eut2 for %d", parentResourceId) + suite.Nilf(err, "error creating new eut2 for %d", parentResourceId) - assertion.Equal(newExternalId, *createdEntity2.ExternalID) + suite.Equal(newExternalId, *createdEntity2.ExternalID) getAllByParentResource, err = service.GetInferenceServices(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &parentResourceId) - assertion.Nilf(err, "error getting all") - assertion.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) + suite.Nilf(err, "error getting all") + suite.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) - assertion.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[2].Id) - assertion.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[0].Id) - assertion.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[1].Id) } // SERVE MODEL -func TestCreateServeModel(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateServeModel() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) - inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) + inferenceServiceId := suite.registerInferenceService(service, registeredModelId, nil, nil, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -2893,7 +2733,7 @@ func TestCreateServeModel(t *testing.T) { Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersionId := *createdVersion.Id createdVersionIdAsInt, _ := converter.StringToInt64(&createdVersionId) // end of data preparation @@ -2914,46 +2754,43 @@ func TestCreateServeModel(t *testing.T) { } createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) - assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) - assertion.NotNil(createdEntity.Id, "created id should not be nil") + suite.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + suite.NotNil(createdEntity.Id, "created id should not be nil") state, _ := openapi.NewExecutionStateFromValue(executionState) - assertion.Equal(entityName, *createdEntity.Name) - assertion.Equal(*state, *createdEntity.LastKnownState) - assertion.Equal(createdVersionId, createdEntity.ModelVersionId) - assertion.Equal(entityDescription, *createdEntity.Description) - assertion.Equal(customString, *(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) + suite.Equal(entityName, *createdEntity.Name) + suite.Equal(*state, *createdEntity.LastKnownState) + suite.Equal(createdVersionId, createdEntity.ModelVersionId) + suite.Equal(entityDescription, *createdEntity.Description) + suite.Equal(customString, *(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) createdEntityId, _ := converter.StringToInt64(createdEntity.Id) - getById, err := client.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ + getById, err := suite.mlmdClient.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ ExecutionIds: []int64{*createdEntityId}, }) - assertion.Nilf(err, "error getting Execution by id %d", createdEntityId) + suite.Nilf(err, "error getting Execution by id %d", createdEntityId) - assertion.Equal(*createdEntityId, *getById.Executions[0].Id) - assertion.Equal(fmt.Sprintf("%s:%s", inferenceServiceId, *createdEntity.Name), *getById.Executions[0].Name) - assertion.Equal(string(*createdEntity.LastKnownState), getById.Executions[0].LastKnownState.String()) - assertion.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) - assertion.Equal(*createdEntity.Description, getById.Executions[0].Properties["description"].GetStringValue()) - assertion.Equal(*(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["custom_string_prop"].GetStringValue()) + suite.Equal(*createdEntityId, *getById.Executions[0].Id) + suite.Equal(fmt.Sprintf("%s:%s", inferenceServiceId, *createdEntity.Name), *getById.Executions[0].Name) + suite.Equal(string(*createdEntity.LastKnownState), getById.Executions[0].LastKnownState.String()) + suite.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) + suite.Equal(*createdEntity.Description, getById.Executions[0].Properties["description"].GetStringValue()) + suite.Equal(*(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["custom_string_prop"].GetStringValue()) inferenceServiceIdAsInt, _ := converter.StringToInt64(&inferenceServiceId) - byCtx, _ := client.GetExecutionsByContext(context.Background(), &proto.GetExecutionsByContextRequest{ + byCtx, _ := suite.mlmdClient.GetExecutionsByContext(context.Background(), &proto.GetExecutionsByContextRequest{ ContextId: (*int64)(inferenceServiceIdAsInt), }) - assertion.Equal(1, len(byCtx.Executions)) - assertion.Equal(*createdEntityId, *byCtx.Executions[0].Id) + suite.Equal(1, len(byCtx.Executions)) + suite.Equal(*createdEntityId, *byCtx.Executions[0].Id) } -func TestCreateServeModelFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestCreateServeModelFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) - inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) + inferenceServiceId := suite.registerInferenceService(service, registeredModelId, nil, nil, nil, nil) // end of data preparation eut := &openapi.ServeModel{ @@ -2972,23 +2809,20 @@ func TestCreateServeModelFailure(t *testing.T) { } _, err := service.UpsertServeModel(eut, nil) - assertion.NotNil(err) - assertion.Equal("missing parentResourceId, cannot create ServeModel without parent resource InferenceService", err.Error()) + suite.NotNil(err) + suite.Equal("missing parentResourceId, cannot create ServeModel without parent resource InferenceService", err.Error()) _, err = service.UpsertServeModel(eut, &inferenceServiceId) - assertion.NotNil(err) - assertion.Equal("no model version found for id 9998", err.Error()) + suite.NotNil(err) + suite.Equal("no model version found for id 9998", err.Error()) } -func TestUpdateServeModel(t *testing.T) { - assertion, conn, client, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateServeModel() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) - inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) + inferenceServiceId := suite.registerInferenceService(service, registeredModelId, nil, nil, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -2997,7 +2831,7 @@ func TestUpdateServeModel(t *testing.T) { Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersionId := *createdVersion.Id createdVersionIdAsInt, _ := converter.StringToInt64(&createdVersionId) // end of data preparation @@ -3018,44 +2852,41 @@ func TestUpdateServeModel(t *testing.T) { } createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) - assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + suite.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) newState := "UNKNOWN" createdEntity.LastKnownState = (*openapi.ExecutionState)(&newState) updatedEntity, err := service.UpsertServeModel(createdEntity, &inferenceServiceId) - assertion.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) + suite.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) createdEntityId, _ := converter.StringToInt64(createdEntity.Id) updatedEntityId, _ := converter.StringToInt64(updatedEntity.Id) - assertion.Equal(createdEntityId, updatedEntityId) + suite.Equal(createdEntityId, updatedEntityId) - getById, err := client.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ + getById, err := suite.mlmdClient.GetExecutionsByID(context.Background(), &proto.GetExecutionsByIDRequest{ ExecutionIds: []int64{*createdEntityId}, }) - assertion.Nilf(err, "error getting by id %d", createdEntityId) + suite.Nilf(err, "error getting by id %d", createdEntityId) - assertion.Equal(*createdEntityId, *getById.Executions[0].Id) - assertion.Equal(fmt.Sprintf("%s:%s", inferenceServiceId, *createdEntity.Name), *getById.Executions[0].Name) - assertion.Equal(string(newState), getById.Executions[0].LastKnownState.String()) - assertion.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) - assertion.Equal(*(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["custom_string_prop"].GetStringValue()) + suite.Equal(*createdEntityId, *getById.Executions[0].Id) + suite.Equal(fmt.Sprintf("%s:%s", inferenceServiceId, *createdEntity.Name), *getById.Executions[0].Name) + suite.Equal(string(newState), getById.Executions[0].LastKnownState.String()) + suite.Equal(*createdVersionIdAsInt, getById.Executions[0].Properties["model_version_id"].GetIntValue()) + suite.Equal(*(*createdEntity.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Executions[0].CustomProperties["custom_string_prop"].GetStringValue()) prevModelVersionId := updatedEntity.ModelVersionId updatedEntity.ModelVersionId = "" updatedEntity, err = service.UpsertServeModel(updatedEntity, &inferenceServiceId) - assertion.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) - assertion.Equal(prevModelVersionId, updatedEntity.ModelVersionId) + suite.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) + suite.Equal(prevModelVersionId, updatedEntity.ModelVersionId) } -func TestUpdateServeModelFailure(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestUpdateServeModelFailure() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) - inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) + inferenceServiceId := suite.registerInferenceService(service, registeredModelId, nil, nil, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -3064,7 +2895,7 @@ func TestUpdateServeModelFailure(t *testing.T) { Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersionId := *createdVersion.Id // end of data preparation @@ -3084,30 +2915,27 @@ func TestUpdateServeModelFailure(t *testing.T) { } createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) - assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) - assertion.NotNil(createdEntity.Id, "created id should not be nil") + suite.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + suite.NotNil(createdEntity.Id, "created id should not be nil") newState := "UNKNOWN" createdEntity.LastKnownState = (*openapi.ExecutionState)(&newState) updatedEntity, err := service.UpsertServeModel(createdEntity, &inferenceServiceId) - assertion.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) + suite.Nilf(err, "error updating entity for %d: %v", inferenceServiceId, err) wrongId := "9998" updatedEntity.Id = &wrongId _, err = service.UpsertServeModel(updatedEntity, &inferenceServiceId) - assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("no ServeModel found for id %s", wrongId), err.Error()) + suite.NotNil(err) + suite.Equal(fmt.Sprintf("no ServeModel found for id %s", wrongId), err.Error()) } -func TestGetServeModelById(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServeModelById() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) - inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) + inferenceServiceId := suite.registerInferenceService(service, registeredModelId, nil, nil, nil, nil) modelVersion := &openapi.ModelVersion{ Name: &modelVersionName, @@ -3116,7 +2944,7 @@ func TestGetServeModelById(t *testing.T) { Author: &author, } createdVersion, err := service.UpsertModelVersion(modelVersion, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersionId := *createdVersion.Id // end of data preparation @@ -3136,47 +2964,44 @@ func TestGetServeModelById(t *testing.T) { } createdEntity, err := service.UpsertServeModel(eut, &inferenceServiceId) - assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + suite.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) getById, err := service.GetServeModelById(*createdEntity.Id) - assertion.Nilf(err, "error getting entity by id %d", *createdEntity.Id) + suite.Nilf(err, "error getting entity by id %d", *createdEntity.Id) state, _ := openapi.NewExecutionStateFromValue(executionState) - assertion.NotNil(createdEntity.Id, "created artifact id should not be nil") - assertion.Equal(entityName, *getById.Name) - assertion.Equal(*state, *getById.LastKnownState) - assertion.Equal(createdVersionId, getById.ModelVersionId) - assertion.Equal(customString, *(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) + suite.NotNil(createdEntity.Id, "created artifact id should not be nil") + suite.Equal(entityName, *getById.Name) + suite.Equal(*state, *getById.LastKnownState) + suite.Equal(createdVersionId, getById.ModelVersionId) + suite.Equal(customString, *(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) - assertion.Equal(*createdEntity, *getById, "artifacts returned during creation and on get by id should be equal") + suite.Equal(*createdEntity, *getById, "artifacts returned during creation and on get by id should be equal") } -func TestGetServeModels(t *testing.T) { - assertion, conn, _, teardown := setup(t) - defer teardown(t) - +func (suite *CoreTestSuite) TestGetServeModels() { // create mode registry service - service := initModelRegistryService(assertion, conn) + service := suite.setupModelRegistryService() - registeredModelId := registerModel(assertion, service, nil, nil) - inferenceServiceId := registerInferenceService(assertion, service, registeredModelId, nil, nil, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) + inferenceServiceId := suite.registerInferenceService(service, registeredModelId, nil, nil, nil, nil) modelVersion1Name := "v1" modelVersion1 := &openapi.ModelVersion{Name: &modelVersion1Name, Description: &modelVersionDescription} createdVersion1, err := service.UpsertModelVersion(modelVersion1, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersion1Id := *createdVersion1.Id modelVersion2Name := "v2" modelVersion2 := &openapi.ModelVersion{Name: &modelVersion2Name, Description: &modelVersionDescription} createdVersion2, err := service.UpsertModelVersion(modelVersion2, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersion2Id := *createdVersion2.Id modelVersion3Name := "v3" modelVersion3 := &openapi.ModelVersion{Name: &modelVersion3Name, Description: &modelVersionDescription} createdVersion3, err := service.UpsertModelVersion(modelVersion3, ®isteredModelId) - assertion.Nilf(err, "error creating new model version for %d", registeredModelId) + suite.Nilf(err, "error creating new model version for %d", registeredModelId) createdVersion3Id := *createdVersion3.Id // end of data preparation @@ -3226,33 +3051,33 @@ func TestGetServeModels(t *testing.T) { } createdEntity1, err := service.UpsertServeModel(eut1, &inferenceServiceId) - assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + suite.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) createdEntity2, err := service.UpsertServeModel(eut2, &inferenceServiceId) - assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + suite.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) createdEntity3, err := service.UpsertServeModel(eut3, &inferenceServiceId) - assertion.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) + suite.Nilf(err, "error creating new ServeModel for %d", inferenceServiceId) createdEntityId1, _ := converter.StringToInt64(createdEntity1.Id) createdEntityId2, _ := converter.StringToInt64(createdEntity2.Id) createdEntityId3, _ := converter.StringToInt64(createdEntity3.Id) getAll, err := service.GetServeModels(api.ListOptions{}, nil) - assertion.Nilf(err, "error getting all ServeModel") - assertion.Equalf(int32(3), getAll.Size, "expected three ServeModel") + suite.Nilf(err, "error getting all ServeModel") + suite.Equalf(int32(3), getAll.Size, "expected three ServeModel") - assertion.Equal(*converter.Int64ToString(createdEntityId1), *getAll.Items[0].Id) - assertion.Equal(*converter.Int64ToString(createdEntityId2), *getAll.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdEntityId3), *getAll.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdEntityId1), *getAll.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdEntityId2), *getAll.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdEntityId3), *getAll.Items[2].Id) orderByLastUpdate := "LAST_UPDATE_TIME" getAllByInferenceService, err := service.GetServeModels(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, }, &inferenceServiceId) - assertion.Nilf(err, "error getting all ServeModels for %d", inferenceServiceId) - assertion.Equalf(int32(3), getAllByInferenceService.Size, "expected three ServeModels for InferenceServiceId %d", inferenceServiceId) + suite.Nilf(err, "error getting all ServeModels for %d", inferenceServiceId) + suite.Equalf(int32(3), getAllByInferenceService.Size, "expected three ServeModels for InferenceServiceId %d", inferenceServiceId) - assertion.Equal(*converter.Int64ToString(createdEntityId1), *getAllByInferenceService.Items[2].Id) - assertion.Equal(*converter.Int64ToString(createdEntityId2), *getAllByInferenceService.Items[1].Id) - assertion.Equal(*converter.Int64ToString(createdEntityId3), *getAllByInferenceService.Items[0].Id) + suite.Equal(*converter.Int64ToString(createdEntityId1), *getAllByInferenceService.Items[2].Id) + suite.Equal(*converter.Int64ToString(createdEntityId2), *getAllByInferenceService.Items[1].Id) + suite.Equal(*converter.Int64ToString(createdEntityId3), *getAllByInferenceService.Items[0].Id) } From da45646a9618cbde6e8a1dce54aa44b3bbbaa351 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 1 Dec 2023 09:22:43 +0100 Subject: [PATCH 175/254] Enhance go api for serving (#219) --- .../api_model_registry_service_service.go | 4 +- pkg/api/api.go | 6 +- pkg/core/core.go | 33 +++++++- pkg/core/core_test.go | 78 ++++++++++++++++--- 4 files changed, 107 insertions(+), 14 deletions(-) diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index dedfaf32..f9472c61 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -236,7 +236,7 @@ func (s *ModelRegistryServiceAPIService) GetEnvironmentInferenceServices(ctx con if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetInferenceServices(listOpts, &servingenvironmentId) + result, err := s.coreApi.GetInferenceServices(listOpts, &servingenvironmentId, nil) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -299,7 +299,7 @@ func (s *ModelRegistryServiceAPIService) GetInferenceServices(ctx context.Contex if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetInferenceServices(listOpts, nil) + result, err := s.coreApi.GetInferenceServices(listOpts, nil, nil) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } diff --git a/pkg/api/api.go b/pkg/api/api.go index 5c33a07a..f24656f7 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -57,6 +57,9 @@ type ModelRegistryApi interface { // GetModelArtifactById retrieve ModelArtifact by id GetModelArtifactById(id string) (*openapi.ModelArtifact, error) + // GetModelArtifactByInferenceService retrieve a ModelArtifact by inference service id + GetModelArtifactByInferenceService(inferenceServiceId string) (*openapi.ModelArtifact, error) + // GetModelArtifactByParams find ModelArtifact instances that match the provided optional params GetModelArtifactByParams(artifactName *string, modelVersionId *string, externalId *string) (*openapi.ModelArtifact, error) @@ -95,7 +98,8 @@ type ModelRegistryApi interface { // GetInferenceServices return all InferenceService properly ordered and sized based on listOptions param // if servingEnvironmentId is provided, return all InferenceService instances belonging to a specific ServingEnvironment - GetInferenceServices(listOptions ListOptions, servingEnvironmentId *string) (*openapi.InferenceServiceList, error) + // if runtime is provided, filter those InferenceService having that runtime + GetInferenceServices(listOptions ListOptions, servingEnvironmentId *string, runtime *string) (*openapi.InferenceServiceList, error) // SERVE MODEL diff --git a/pkg/core/core.go b/pkg/core/core.go index 0dfce13c..4ab1640a 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -3,6 +3,7 @@ package core import ( "context" "fmt" + "strings" "github.com/golang/glog" "github.com/opendatahub-io/model-registry/internal/apiutils" @@ -681,6 +682,25 @@ func (serv *ModelRegistryService) GetModelArtifactById(id string) (*openapi.Mode return result, nil } +func (serv *ModelRegistryService) GetModelArtifactByInferenceService(inferenceServiceId string) (*openapi.ModelArtifact, error) { + + mv, err := serv.GetModelVersionByInferenceService(inferenceServiceId) + if err != nil { + return nil, err + } + + artifactList, err := serv.GetModelArtifacts(api.ListOptions{}, mv.Id) + if err != nil { + return nil, err + } + + if artifactList.Size == 0 { + return nil, fmt.Errorf("no artifacts found for model version %s", *mv.Id) + } + + return &artifactList.Items[0], nil +} + func (serv *ModelRegistryService) GetModelArtifactByParams(artifactName *string, parentResourceId *string, externalId *string) (*openapi.ModelArtifact, error) { var artifact0 *proto.Artifact @@ -1104,17 +1124,26 @@ func (serv *ModelRegistryService) GetInferenceServiceByParams(name *string, pare return toReturn, nil } -func (serv *ModelRegistryService) GetInferenceServices(listOptions api.ListOptions, parentResourceId *string) (*openapi.InferenceServiceList, error) { +func (serv *ModelRegistryService) GetInferenceServices(listOptions api.ListOptions, parentResourceId *string, runtime *string) (*openapi.InferenceServiceList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } + queries := []string{} if parentResourceId != nil { queryParentCtxId := fmt.Sprintf("parent_contexts_a.id = %s", *parentResourceId) - listOperationOptions.FilterQuery = &queryParentCtxId + queries = append(queries, queryParentCtxId) + } + + if runtime != nil { + queryRuntimeProp := fmt.Sprintf("properties.runtime.string_value = \"%s\"", *runtime) + queries = append(queries, queryRuntimeProp) } + query := strings.Join(queries, " and ") + listOperationOptions.FilterQuery = &query + contextsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ TypeName: inferenceServiceTypeName, Options: listOperationOptions, diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index f33baf5b..5b0bfc5e 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -2417,10 +2417,9 @@ func (suite *CoreTestSuite) TestGetRegisteredModelByInferenceServiceId() { createdEntity, err := service.UpsertInferenceService(eut) suite.Nilf(err, "error creating new eut for %v", parentResourceId) suite.NotNilf(createdEntity.Id, "created eut should not have nil Id") - createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getRM, err := service.GetRegisteredModelByInferenceService(*createdEntity.Id) - suite.Nilf(err, "error getting using id %d", *createdEntityId) + suite.Nilf(err, "error getting using id %s", *createdEntity.Id) suite.Equal(registeredModelId, *getRM.Id, "returned id should match the original registeredModelId") } @@ -2462,10 +2461,9 @@ func (suite *CoreTestSuite) TestGetModelVersionByInferenceServiceId() { } createdEntity, err := service.UpsertInferenceService(eut) suite.Nilf(err, "error creating new eut for %v", parentResourceId) - createdEntityId, _ := converter.StringToInt64(createdEntity.Id) getVModel, err := service.GetModelVersionByInferenceService(*createdEntity.Id) - suite.Nilf(err, "error getting using id %d", *createdEntityId) + suite.Nilf(err, "error getting using id %s", *createdEntity.Id) suite.Equal(createdVersion2Id, *getVModel.Id, "returned id shall be the latest ModelVersion by creation order") // here we used the returned entity (so ID is populated), and we update to specify the "ID of the ModelVersion to serve" @@ -2474,10 +2472,61 @@ func (suite *CoreTestSuite) TestGetModelVersionByInferenceServiceId() { suite.Nilf(err, "error updating eut for %v", parentResourceId) getVModel, err = service.GetModelVersionByInferenceService(*createdEntity.Id) - suite.Nilf(err, "error getting using id %d", *createdEntityId) + suite.Nilf(err, "error getting using id %s", *createdEntity.Id) suite.Equal(createdVersion1Id, *getVModel.Id, "returned id shall be the specified one") } +func (suite *CoreTestSuite) TestGetModelArtifactByInferenceServiceId() { + // create mode registry service + service := suite.setupModelRegistryService() + + parentResourceId := suite.registerServingEnvironment(service, nil, nil) + registeredModelId := suite.registerModel(service, nil, nil) + + modelVersion1Name := "v1" + modelVersion1 := &openapi.ModelVersion{Name: &modelVersion1Name, Description: &modelVersionDescription} + createdVersion1, err := service.UpsertModelVersion(modelVersion1, ®isteredModelId) + suite.Nilf(err, "error creating new model version for %s", registeredModelId) + modelArtifact1Name := "v1-artifact" + modelArtifact1 := &openapi.ModelArtifact{Name: &modelArtifact1Name} + createdArtifact1, err := service.UpsertModelArtifact(modelArtifact1, createdVersion1.Id) + suite.Nilf(err, "error creating new model artifact for %s", *createdVersion1.Id) + + modelVersion2Name := "v2" + modelVersion2 := &openapi.ModelVersion{Name: &modelVersion2Name, Description: &modelVersionDescription} + createdVersion2, err := service.UpsertModelVersion(modelVersion2, ®isteredModelId) + suite.Nilf(err, "error creating new model version for %s", registeredModelId) + modelArtifact2Name := "v2-artifact" + modelArtifact2 := &openapi.ModelArtifact{Name: &modelArtifact2Name} + createdArtifact2, err := service.UpsertModelArtifact(modelArtifact2, createdVersion2.Id) + suite.Nilf(err, "error creating new model artifact for %s", *createdVersion2.Id) + // end of data preparation + + eut := &openapi.InferenceService{ + Name: &entityName, + ExternalID: &entityExternalId2, + Description: &entityDescription, + ServingEnvironmentId: parentResourceId, + RegisteredModelId: registeredModelId, + ModelVersionId: nil, // first we test by unspecified + } + createdEntity, err := service.UpsertInferenceService(eut) + suite.Nilf(err, "error creating new eut for %v", parentResourceId) + + getModelArt, err := service.GetModelArtifactByInferenceService(*createdEntity.Id) + suite.Nilf(err, "error getting using id %s", *createdEntity.Id) + suite.Equal(*createdArtifact2.Id, *getModelArt.Id, "returned id shall be the latest ModelVersion by creation order") + + // here we used the returned entity (so ID is populated), and we update to specify the "ID of the ModelVersion to serve" + createdEntity.ModelVersionId = createdVersion1.Id + _, err = service.UpsertInferenceService(createdEntity) + suite.Nilf(err, "error updating eut for %v", parentResourceId) + + getModelArt, err = service.GetModelArtifactByInferenceService(*createdEntity.Id) + suite.Nilf(err, "error getting using id %s", *createdEntity.Id) + suite.Equal(*createdArtifact1.Id, *getModelArt.Id, "returned id shall be the specified one") +} + func (suite *CoreTestSuite) TestGetInferenceServiceByParamsWithNoResults() { // create mode registry service service := suite.setupModelRegistryService() @@ -2623,6 +2672,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &entityExternalId2, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, + Runtime: of("model-server0"), } secondName := "v2" @@ -2632,6 +2682,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &secondExtId, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, + Runtime: of("model-server1"), } thirdName := "v3" @@ -2641,6 +2692,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &thirdExtId, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, + Runtime: of("model-server2"), } createdEntity1, err := service.UpsertInferenceService(eut1) @@ -2663,6 +2715,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &anotherExtId, ServingEnvironmentId: anotherParentResourceId, RegisteredModelId: registeredModelId, + Runtime: of("model-server3"), } _, err = service.UpsertInferenceService(eutAnother) @@ -2672,11 +2725,11 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { createdId2, _ := converter.StringToInt64(createdEntity2.Id) createdId3, _ := converter.StringToInt64(createdEntity3.Id) - getAll, err := service.GetInferenceServices(api.ListOptions{}, nil) + getAll, err := service.GetInferenceServices(api.ListOptions{}, nil, nil) suite.Nilf(err, "error getting all") suite.Equal(int32(4), getAll.Size, "expected 4 across all parent resources") - getAllByParentResource, err := service.GetInferenceServices(api.ListOptions{}, &parentResourceId) + getAllByParentResource, err := service.GetInferenceServices(api.ListOptions{}, &parentResourceId, nil) suite.Nilf(err, "error getting all") suite.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) @@ -2684,12 +2737,19 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { suite.Equal(*converter.Int64ToString(createdId2), *getAllByParentResource.Items[1].Id) suite.Equal(*converter.Int64ToString(createdId3), *getAllByParentResource.Items[2].Id) + modelServer := "model-server1" + getAllByParentResourceAndRuntime, err := service.GetInferenceServices(api.ListOptions{}, &parentResourceId, &modelServer) + suite.Nilf(err, "error getting all") + suite.Equalf(int32(1), getAllByParentResourceAndRuntime.Size, "expected 1 for parent resource %s and runtime %s", parentResourceId, modelServer) + + suite.Equal(*converter.Int64ToString(createdId1), *getAllByParentResource.Items[0].Id) + // order by last update time, expecting last created as first orderByLastUpdate := "LAST_UPDATE_TIME" getAllByParentResource, err = service.GetInferenceServices(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, - }, &parentResourceId) + }, &parentResourceId, nil) suite.Nilf(err, "error getting all") suite.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) @@ -2708,7 +2768,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { getAllByParentResource, err = service.GetInferenceServices(api.ListOptions{ OrderBy: &orderByLastUpdate, SortOrder: &descOrderDirection, - }, &parentResourceId) + }, &parentResourceId, nil) suite.Nilf(err, "error getting all") suite.Equalf(int32(3), getAllByParentResource.Size, "expected 3 for parent resource %d", parentResourceId) From 63807ee1756689e09c25741b1888cb70ed30675d Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 1 Dec 2023 09:43:46 +0100 Subject: [PATCH 176/254] Add go core library documentation (#207) * Add go doc for model registry service * Add go core library getting started guide --- README.md | 2 +- doc/mr_go_library.md | 145 ++++++++++++++++++++++++++++++++++++++++++ pkg/api/api.go | 10 +-- pkg/core/core.go | 145 +++++++++++++++++++++++++++--------------- pkg/core/core_test.go | 14 ++-- 5 files changed, 254 insertions(+), 62 deletions(-) create mode 100644 doc/mr_go_library.md diff --git a/README.md b/README.md index 597ea6ac..65006b63 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ It provides a model registry domain-specific [api](internal/core/api.go) that is ### Model registry library -TODO +For more background on Model Registry Go core library and instructions on using it, please check [getting started guide](./doc/mr_go_library.md). ## Development diff --git a/doc/mr_go_library.md b/doc/mr_go_library.md new file mode 100644 index 00000000..a0653bb3 --- /dev/null +++ b/doc/mr_go_library.md @@ -0,0 +1,145 @@ +# Model Registry Service + +The Model Registry Service go library provides a convenient interface for managing and interacting with models, model versions, artifacts, serving environments, inference services, and serve models through the underlying [ML Metadata (MLMD)](https://github.com/google/ml-metadata) service. + +## Installation + +The recommended way is using `go get`, from your custom project run: +```bash +go get github.com/opendatahub-io/model-registry +``` + +## Getting Started + +Model Registry Service is an high level Go client (or library) for ML Metadata (MLMD) store/service. +It provides model registry metadata capabilities, e.g., store and retrieve ML models metadata and related artifacts, through a custom defined [API](../pkg/api/api.go). + +### Prerequisites + +* MLMD server, check [ml-metadata doc](https://github.com/google/ml-metadata/blob/f0fef74eae2bdf6650a79ba976b36bea0b777c2e/g3doc/get_started.md#use-mlmd-with-a-remote-grpc-server) for more details on how to startup a MLMD store server. +* Go >= 1.19 + +### Usage + +Assuming that MLMD server is already running at `localhost:9090`, as first step you should setup a gRPC connection to the server: + +```go +import ( + "context" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +conn, err := grpc.DialContext( + context.Background(), + "localhost:9090", + grpc.WithReturnConnectionError(), + grpc.WithBlock(), // optional + grpc.WithTransportCredentials(insecure.NewCredentials()), +) +if err != nil { + return fmt.Errorf("error dialing connection to mlmd server localhost:9090: %v", err) +} +defer conn.Close() +``` + +> NOTE: check [grpc doc](https://pkg.go.dev/google.golang.org/grpc#DialContext) for more details. + +Once the gRPC connection is setup, let's create the `ModelRegistryService`: + +```go +import ( + "fmt" + "github.com/opendatahub-io/model-registry/pkg/core" +) + +service, err := core.NewModelRegistryService(conn) +if err != nil { + return fmt.Errorf("error creating model registry core service: %v", err) +} +``` + +Everything is ready, you can start using the `ModelRegistryService` library! + +Here some usage examples: + +#### Model Registration + +Create a `RegisteredModel` + +```go +modelName := "MODEL_NAME" +modelDescription := "MODEL_DESCRIPTION" + +// register a new model +registeredModel, err = service.UpsertRegisteredModel(&openapi.RegisteredModel{ + Name: &modelName, + Description: &modelDescription, +}) +if err != nil { + return fmt.Errorf("error registering model: %v", err) +} +``` + +Create a new `ModelVersion` for the previous registered model + +```go +versionName := "VERSION_NAME" +versionDescription := "VERSION_DESCRIPTION" +versionScore := 0.83 + +// register model version +modelVersion, err = service.UpsertModelVersion(&openapi.ModelVersion{ + Name: &versionName, + Description: &versionDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "score": { + MetadataDoubleValue: &openapi.MetadataDoubleValue{ + DoubleValue: &versionScore, + }, + }, + }, +}, registeredModel.Id) +if err != nil { + return fmt.Errorf("error registering model version: %v", err) +} +``` + +Create a new `ModelArtifact` for the newly created version + +```go +artifactName := "ARTIFACT_NAME" +artifactDescription := "ARTIFACT_DESCRIPTION" +artifactUri := "ARTIFACT_URI" + +// register model artifact +modelArtifact, err := service.UpsertModelArtifact(&openapi.ModelArtifact{ + Name: &artifactName, + Description: &artifactDescription, + Uri: &artifactUri, +}, modelVersion.Id) +if err != nil { + return fmt.Errorf("error creating model artifact: %v", err) +} +``` + +#### Model Query + +Get `RegisteredModel` by name, for now the `name` must match. +```go +modelName := "QUERY_MODEL_NAME" +registeredModel, err := service.GetRegisteredModelByParams(&modelName, nil) +if err != nil { + log.Printf("unable to find model %s: %v", getModelCfg.RegisteredModelName, err) + return err +} +``` + +Get all `ModelVersion` associated to a specific registered model + +```go +allVersions, err := service.GetModelVersions(api.ListOptions{}, registeredModel.Id) +if err != nil { + return fmt.Errorf("error retrieving model versions for model %s: %v", *registeredModel.Id, err) +} +``` \ No newline at end of file diff --git a/pkg/api/api.go b/pkg/api/api.go index f24656f7..dd2dd4bc 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -2,11 +2,13 @@ package api import "github.com/opendatahub-io/model-registry/pkg/openapi" +// ListOptions provides options for listing entities with pagination and sorting. +// It includes parameters such as PageSize, OrderBy, SortOrder, and NextPageToken. type ListOptions struct { - PageSize *int32 - OrderBy *string - SortOrder *string - NextPageToken *string + PageSize *int32 // The maximum number of entities to be returned per page. + OrderBy *string // The field by which entities are ordered. + SortOrder *string // The sorting order, which can be "ASC" (ascending) or "DESC" (descending). + NextPageToken *string // A token to retrieve the next page of entities in a paginated result set. } // ModelRegistryApi defines the external API for the Model Registry library diff --git a/pkg/core/core.go b/pkg/core/core.go index 4ab1640a..3b36833e 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -33,7 +33,11 @@ type ModelRegistryService struct { openapiConv *generated.OpenAPIConverterImpl } -// NewModelRegistryService create a fresh instance of ModelRegistryService, taking care of setting up needed MLMD Types +// NewModelRegistryService creates a new instance of the ModelRegistryService, initializing it with the provided gRPC client connection. +// It sets up the necessary context and artifact types in the MLMD service. +// +// Parameters: +// - cc: A gRPC client connection to the underlying MLMD service func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, error) { client := proto.NewMetadataStoreServiceClient(cc) @@ -163,6 +167,8 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, // REGISTERED MODELS +// UpsertRegisteredModel creates a new registered model if the given registered model's ID is nil, +// or updates an existing registered model if the ID is provided. func (serv *ModelRegistryService) UpsertRegisteredModel(registeredModel *openapi.RegisteredModel) (*openapi.RegisteredModel, error) { var err error var existing *openapi.RegisteredModel @@ -206,6 +212,7 @@ func (serv *ModelRegistryService) UpsertRegisteredModel(registeredModel *openapi return model, nil } +// GetRegisteredModelById retrieves a registered model by its unique identifier (ID). func (serv *ModelRegistryService) GetRegisteredModelById(id string) (*openapi.RegisteredModel, error) { glog.Infof("Getting registered model %s", id) @@ -237,6 +244,7 @@ func (serv *ModelRegistryService) GetRegisteredModelById(id string) (*openapi.Re return regModel, nil } +// GetRegisteredModelByInferenceService retrieves a registered model associated with the specified inference service ID. func (serv *ModelRegistryService) GetRegisteredModelByInferenceService(inferenceServiceId string) (*openapi.RegisteredModel, error) { is, err := serv.GetInferenceServiceById(inferenceServiceId) if err != nil { @@ -245,6 +253,7 @@ func (serv *ModelRegistryService) GetRegisteredModelByInferenceService(inference return serv.GetRegisteredModelById(is.RegisteredModelId) } +// getRegisteredModelByVersionId retrieves a registered model associated with the specified model version ID. func (serv *ModelRegistryService) getRegisteredModelByVersionId(id string) (*openapi.RegisteredModel, error) { glog.Infof("Getting registered model for model version %s", id) @@ -276,6 +285,8 @@ func (serv *ModelRegistryService) getRegisteredModelByVersionId(id string) (*ope return regModel, nil } +// GetRegisteredModelByParams retrieves a registered model based on specified parameters, such as name or external ID. +// If multiple or no registered models are found, an error is returned accordingly. func (serv *ModelRegistryService) GetRegisteredModelByParams(name *string, externalId *string) (*openapi.RegisteredModel, error) { glog.Infof("Getting registered model by params name=%v, externalId=%v", name, externalId) @@ -313,6 +324,7 @@ func (serv *ModelRegistryService) GetRegisteredModelByParams(name *string, exter return regModel, nil } +// GetRegisteredModels retrieves a list of registered models based on the provided list options. func (serv *ModelRegistryService) GetRegisteredModels(listOptions api.ListOptions) (*openapi.RegisteredModelList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { @@ -346,7 +358,9 @@ func (serv *ModelRegistryService) GetRegisteredModels(listOptions api.ListOption // MODEL VERSIONS -func (serv *ModelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, parentResourceId *string) (*openapi.ModelVersion, error) { +// UpsertModelVersion creates a new model version if the provided model version's ID is nil, +// or updates an existing model version if the ID is provided. +func (serv *ModelRegistryService) UpsertModelVersion(modelVersion *openapi.ModelVersion, registeredModelId *string) (*openapi.ModelVersion, error) { var err error var existing *openapi.ModelVersion var registeredModel *openapi.RegisteredModel @@ -354,10 +368,10 @@ func (serv *ModelRegistryService) UpsertModelVersion(modelVersion *openapi.Model if modelVersion.Id == nil { // create glog.Info("Creating new model version") - if parentResourceId == nil { + if registeredModelId == nil { return nil, fmt.Errorf("missing registered model id, cannot create model version without registered model") } - registeredModel, err = serv.GetRegisteredModelById(*parentResourceId) + registeredModel, err = serv.GetRegisteredModelById(*registeredModelId) if err != nil { return nil, err } @@ -422,6 +436,7 @@ func (serv *ModelRegistryService) UpsertModelVersion(modelVersion *openapi.Model return model, nil } +// GetModelVersionById retrieves a model version by its unique identifier (ID). func (serv *ModelRegistryService) GetModelVersionById(id string) (*openapi.ModelVersion, error) { idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -451,6 +466,7 @@ func (serv *ModelRegistryService) GetModelVersionById(id string) (*openapi.Model return modelVer, nil } +// GetModelVersionByInferenceService retrieves the model version associated with the specified inference service ID. func (serv *ModelRegistryService) GetModelVersionByInferenceService(inferenceServiceId string) (*openapi.ModelVersion, error) { is, err := serv.GetInferenceServiceById(inferenceServiceId) if err != nil { @@ -472,6 +488,7 @@ func (serv *ModelRegistryService) GetModelVersionByInferenceService(inferenceSer return &versions.Items[0], nil } +// getModelVersionByArtifactId retrieves the model version associated with the specified model artifact ID. func (serv *ModelRegistryService) getModelVersionByArtifactId(id string) (*openapi.ModelVersion, error) { glog.Infof("Getting model version for model artifact %s", id) @@ -503,14 +520,16 @@ func (serv *ModelRegistryService) getModelVersionByArtifactId(id string) (*opena return modelVersion, nil } -func (serv *ModelRegistryService) GetModelVersionByParams(versionName *string, parentResourceId *string, externalId *string) (*openapi.ModelVersion, error) { +// GetModelVersionByParams retrieves a model version based on specified parameters, such as (version name and registered model ID), or external ID. +// If multiple or no model versions are found, an error is returned. +func (serv *ModelRegistryService) GetModelVersionByParams(versionName *string, registeredModelId *string, externalId *string) (*openapi.ModelVersion, error) { filterQuery := "" - if versionName != nil && parentResourceId != nil { - filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *versionName)) + if versionName != nil && registeredModelId != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(registeredModelId, *versionName)) } else if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) } else { - return nil, fmt.Errorf("invalid parameters call, supply either (versionName and parentResourceId), or externalId") + return nil, fmt.Errorf("invalid parameters call, supply either (versionName and registeredModelId), or externalId") } getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ @@ -524,11 +543,11 @@ func (serv *ModelRegistryService) GetModelVersionByParams(versionName *string, p } if len(getByParamsResp.Contexts) > 1 { - return nil, fmt.Errorf("multiple model versions found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(versionName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("multiple model versions found for versionName=%v, registeredModelId=%v, externalId=%v", apiutils.ZeroIfNil(versionName), apiutils.ZeroIfNil(registeredModelId), apiutils.ZeroIfNil(externalId)) } if len(getByParamsResp.Contexts) == 0 { - return nil, fmt.Errorf("no model versions found for versionName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(versionName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("no model versions found for versionName=%v, registeredModelId=%v, externalId=%v", apiutils.ZeroIfNil(versionName), apiutils.ZeroIfNil(registeredModelId), apiutils.ZeroIfNil(externalId)) } modelVer, err := serv.mapper.MapToModelVersion(getByParamsResp.Contexts[0]) @@ -538,14 +557,15 @@ func (serv *ModelRegistryService) GetModelVersionByParams(versionName *string, p return modelVer, nil } -func (serv *ModelRegistryService) GetModelVersions(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelVersionList, error) { +// GetModelVersions retrieves a list of model versions based on the provided list options and optional registered model ID. +func (serv *ModelRegistryService) GetModelVersions(listOptions api.ListOptions, registeredModelId *string) (*openapi.ModelVersionList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } - if parentResourceId != nil { - queryParentCtxId := fmt.Sprintf("parent_contexts_a.id = %s", *parentResourceId) + if registeredModelId != nil { + queryParentCtxId := fmt.Sprintf("parent_contexts_a.id = %s", *registeredModelId) listOperationOptions.FilterQuery = &queryParentCtxId } @@ -577,17 +597,21 @@ func (serv *ModelRegistryService) GetModelVersions(listOptions api.ListOptions, // MODEL ARTIFACTS -func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, parentResourceId *string) (*openapi.ModelArtifact, error) { +// UpsertModelArtifact creates a new model artifact if the provided model artifact's ID is nil, +// or updates an existing model artifact if the ID is provided. +// If a model version ID is provided and the model artifact is newly created, establishes an +// explicit attribution between the model version and the created model artifact. +func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *string) (*openapi.ModelArtifact, error) { var err error var existing *openapi.ModelArtifact if modelArtifact.Id == nil { // create glog.Info("Creating new model artifact") - if parentResourceId == nil { + if modelVersionId == nil { return nil, fmt.Errorf("missing model version id, cannot create model artifact without model version") } - _, err = serv.GetModelVersionById(*parentResourceId) + _, err = serv.GetModelVersionById(*modelVersionId) if err != nil { return nil, err } @@ -611,7 +635,7 @@ func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } } - artifact, err := serv.mapper.MapFromModelArtifact(modelArtifact, parentResourceId) + artifact, err := serv.mapper.MapFromModelArtifact(modelArtifact, modelVersionId) if err != nil { return nil, err } @@ -624,8 +648,8 @@ func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } // add explicit Attribution between Artifact and ModelVersion - if parentResourceId != nil && modelArtifact.Id == nil { - modelVersionId, err := converter.StringToInt64(parentResourceId) + if modelVersionId != nil && modelArtifact.Id == nil { + modelVersionId, err := converter.StringToInt64(modelVersionId) if err != nil { return nil, err } @@ -653,6 +677,7 @@ func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod return mapped, nil } +// GetModelArtifactById retrieves a model artifact by its unique identifier (ID). func (serv *ModelRegistryService) GetModelArtifactById(id string) (*openapi.ModelArtifact, error) { idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -682,6 +707,7 @@ func (serv *ModelRegistryService) GetModelArtifactById(id string) (*openapi.Mode return result, nil } +// GetModelArtifactByInferenceService retrieves the model artifact associated with the specified inference service ID. func (serv *ModelRegistryService) GetModelArtifactByInferenceService(inferenceServiceId string) (*openapi.ModelArtifact, error) { mv, err := serv.GetModelVersionByInferenceService(inferenceServiceId) @@ -701,16 +727,18 @@ func (serv *ModelRegistryService) GetModelArtifactByInferenceService(inferenceSe return &artifactList.Items[0], nil } -func (serv *ModelRegistryService) GetModelArtifactByParams(artifactName *string, parentResourceId *string, externalId *string) (*openapi.ModelArtifact, error) { +// GetModelArtifactByParams retrieves a model artifact based on specified parameters, such as (artifact name and model version ID), or external ID. +// If multiple or no model artifacts are found, an error is returned. +func (serv *ModelRegistryService) GetModelArtifactByParams(artifactName *string, modelVersionId *string, externalId *string) (*openapi.ModelArtifact, error) { var artifact0 *proto.Artifact filterQuery := "" if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) - } else if artifactName != nil && parentResourceId != nil { - filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *artifactName)) + } else if artifactName != nil && modelVersionId != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(modelVersionId, *artifactName)) } else { - return nil, fmt.Errorf("invalid parameters call, supply either (artifactName and parentResourceId), or externalId") + return nil, fmt.Errorf("invalid parameters call, supply either (artifactName and modelVersionId), or externalId") } artifactsResponse, err := serv.mlmdClient.GetArtifactsByType(context.Background(), &proto.GetArtifactsByTypeRequest{ @@ -724,11 +752,11 @@ func (serv *ModelRegistryService) GetModelArtifactByParams(artifactName *string, } if len(artifactsResponse.Artifacts) > 1 { - return nil, fmt.Errorf("multiple model artifacts found for artifactName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(artifactName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("multiple model artifacts found for artifactName=%v, modelVersionId=%v, externalId=%v", apiutils.ZeroIfNil(artifactName), apiutils.ZeroIfNil(modelVersionId), apiutils.ZeroIfNil(externalId)) } if len(artifactsResponse.Artifacts) == 0 { - return nil, fmt.Errorf("no model artifacts found for artifactName=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(artifactName), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("no model artifacts found for artifactName=%v, modelVersionId=%v, externalId=%v", apiutils.ZeroIfNil(artifactName), apiutils.ZeroIfNil(modelVersionId), apiutils.ZeroIfNil(externalId)) } artifact0 = artifactsResponse.Artifacts[0] @@ -741,7 +769,8 @@ func (serv *ModelRegistryService) GetModelArtifactByParams(artifactName *string, return result, nil } -func (serv *ModelRegistryService) GetModelArtifacts(listOptions api.ListOptions, parentResourceId *string) (*openapi.ModelArtifactList, error) { +// GetModelArtifacts retrieves a list of model artifacts based on the provided list options and optional model version ID. +func (serv *ModelRegistryService) GetModelArtifacts(listOptions api.ListOptions, modelVersionId *string) (*openapi.ModelArtifactList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -749,8 +778,8 @@ func (serv *ModelRegistryService) GetModelArtifacts(listOptions api.ListOptions, var artifacts []*proto.Artifact var nextPageToken *string - if parentResourceId != nil { - ctxId, err := converter.StringToInt64(parentResourceId) + if modelVersionId != nil { + ctxId, err := converter.StringToInt64(modelVersionId) if err != nil { return nil, err } @@ -795,6 +824,8 @@ func (serv *ModelRegistryService) GetModelArtifacts(listOptions api.ListOptions, // SERVING ENVIRONMENT +// UpsertServingEnvironment creates a new serving environment if the provided serving environment's ID is nil, +// or updates an existing serving environment if the ID is provided. func (serv *ModelRegistryService) UpsertServingEnvironment(servingEnvironment *openapi.ServingEnvironment) (*openapi.ServingEnvironment, error) { var err error var existing *openapi.ServingEnvironment @@ -838,6 +869,7 @@ func (serv *ModelRegistryService) UpsertServingEnvironment(servingEnvironment *o return openapiModel, nil } +// GetServingEnvironmentById retrieves a serving environment by its unique identifier (ID). func (serv *ModelRegistryService) GetServingEnvironmentById(id string) (*openapi.ServingEnvironment, error) { glog.Infof("Getting serving environment %s", id) @@ -869,6 +901,8 @@ func (serv *ModelRegistryService) GetServingEnvironmentById(id string) (*openapi return openapiModel, nil } +// GetServingEnvironmentByParams retrieves a serving environment based on specified parameters, such as name or external ID. +// If multiple or no serving environments are found, an error is returned accordingly. func (serv *ModelRegistryService) GetServingEnvironmentByParams(name *string, externalId *string) (*openapi.ServingEnvironment, error) { glog.Infof("Getting serving environment by params name=%v, externalId=%v", name, externalId) @@ -906,6 +940,7 @@ func (serv *ModelRegistryService) GetServingEnvironmentByParams(name *string, ex return openapiModel, nil } +// GetServingEnvironments retrieves a list of serving environments based on the provided list options. func (serv *ModelRegistryService) GetServingEnvironments(listOptions api.ListOptions) (*openapi.ServingEnvironmentList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { @@ -939,17 +974,17 @@ func (serv *ModelRegistryService) GetServingEnvironments(listOptions api.ListOpt // INFERENCE SERVICE +// UpsertInferenceService creates a new inference service if the provided inference service's ID is nil, +// or updates an existing inference service if the ID is provided. func (serv *ModelRegistryService) UpsertInferenceService(inferenceService *openapi.InferenceService) (*openapi.InferenceService, error) { var err error var existing *openapi.InferenceService var servingEnvironment *openapi.ServingEnvironment - // for InferenceService, is part of model payload. - parentResourceId := inferenceService.ServingEnvironmentId if inferenceService.Id == nil { // create glog.Info("Creating new InferenceService") - servingEnvironment, err = serv.GetServingEnvironmentById(parentResourceId) + servingEnvironment, err = serv.GetServingEnvironmentById(inferenceService.ServingEnvironmentId) if err != nil { return nil, err } @@ -1027,6 +1062,7 @@ func (serv *ModelRegistryService) UpsertInferenceService(inferenceService *opena return toReturn, nil } +// getServingEnvironmentByInferenceServiceId retrieves the serving environment associated with the specified inference service ID. func (serv *ModelRegistryService) getServingEnvironmentByInferenceServiceId(id string) (*openapi.ServingEnvironment, error) { glog.Infof("Getting ServingEnvironment for InferenceService %s", id) @@ -1058,6 +1094,7 @@ func (serv *ModelRegistryService) getServingEnvironmentByInferenceServiceId(id s return toReturn, nil } +// GetInferenceServiceById retrieves an inference service by its unique identifier (ID). func (serv *ModelRegistryService) GetInferenceServiceById(id string) (*openapi.InferenceService, error) { glog.Infof("Getting InferenceService by id %s", id) @@ -1089,14 +1126,16 @@ func (serv *ModelRegistryService) GetInferenceServiceById(id string) (*openapi.I return toReturn, nil } -func (serv *ModelRegistryService) GetInferenceServiceByParams(name *string, parentResourceId *string, externalId *string) (*openapi.InferenceService, error) { +// GetInferenceServiceByParams retrieves an inference service based on specified parameters, such as (name and serving environment ID), or external ID. +// If multiple or no serving environments are found, an error is returned accordingly. +func (serv *ModelRegistryService) GetInferenceServiceByParams(name *string, servingEnvironmentId *string, externalId *string) (*openapi.InferenceService, error) { filterQuery := "" - if name != nil && parentResourceId != nil { - filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(parentResourceId, *name)) + if name != nil && servingEnvironmentId != nil { + filterQuery = fmt.Sprintf("name = \"%s\"", converter.PrefixWhenOwned(servingEnvironmentId, *name)) } else if externalId != nil { filterQuery = fmt.Sprintf("external_id = \"%s\"", *externalId) } else { - return nil, fmt.Errorf("invalid parameters call, supply either (name and parentResourceId), or externalId") + return nil, fmt.Errorf("invalid parameters call, supply either (name and servingEnvironmentId), or externalId") } getByParamsResp, err := serv.mlmdClient.GetContextsByType(context.Background(), &proto.GetContextsByTypeRequest{ @@ -1110,11 +1149,11 @@ func (serv *ModelRegistryService) GetInferenceServiceByParams(name *string, pare } if len(getByParamsResp.Contexts) > 1 { - return nil, fmt.Errorf("multiple inference services found for name=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("multiple inference services found for name=%v, servingEnvironmentId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(servingEnvironmentId), apiutils.ZeroIfNil(externalId)) } if len(getByParamsResp.Contexts) == 0 { - return nil, fmt.Errorf("no inference services found for name=%v, parentResourceId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(parentResourceId), apiutils.ZeroIfNil(externalId)) + return nil, fmt.Errorf("no inference services found for name=%v, servingEnvironmentId=%v, externalId=%v", apiutils.ZeroIfNil(name), apiutils.ZeroIfNil(servingEnvironmentId), apiutils.ZeroIfNil(externalId)) } toReturn, err := serv.mapper.MapToInferenceService(getByParamsResp.Contexts[0]) @@ -1124,15 +1163,16 @@ func (serv *ModelRegistryService) GetInferenceServiceByParams(name *string, pare return toReturn, nil } -func (serv *ModelRegistryService) GetInferenceServices(listOptions api.ListOptions, parentResourceId *string, runtime *string) (*openapi.InferenceServiceList, error) { +// GetInferenceServices retrieves a list of inference services based on the provided list options and optional serving environment ID and runtime. +func (serv *ModelRegistryService) GetInferenceServices(listOptions api.ListOptions, servingEnvironmentId *string, runtime *string) (*openapi.InferenceServiceList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err } queries := []string{} - if parentResourceId != nil { - queryParentCtxId := fmt.Sprintf("parent_contexts_a.id = %s", *parentResourceId) + if servingEnvironmentId != nil { + queryParentCtxId := fmt.Sprintf("parent_contexts_a.id = %s", *servingEnvironmentId) queries = append(queries, queryParentCtxId) } @@ -1172,17 +1212,19 @@ func (serv *ModelRegistryService) GetInferenceServices(listOptions api.ListOptio // SERVE MODEL -func (serv *ModelRegistryService) UpsertServeModel(serveModel *openapi.ServeModel, parentResourceId *string) (*openapi.ServeModel, error) { +// UpsertServeModel creates a new serve model if the provided serve model's ID is nil, +// or updates an existing serve model if the ID is provided. +func (serv *ModelRegistryService) UpsertServeModel(serveModel *openapi.ServeModel, inferenceServiceId *string) (*openapi.ServeModel, error) { var err error var existing *openapi.ServeModel if serveModel.Id == nil { // create glog.Info("Creating new ServeModel") - if parentResourceId == nil { - return nil, fmt.Errorf("missing parentResourceId, cannot create ServeModel without parent resource InferenceService") + if inferenceServiceId == nil { + return nil, fmt.Errorf("missing inferenceServiceId, cannot create ServeModel without parent resource InferenceService") } - _, err = serv.GetInferenceServiceById(*parentResourceId) + _, err = serv.GetInferenceServiceById(*inferenceServiceId) if err != nil { return nil, err } @@ -1218,7 +1260,7 @@ func (serv *ModelRegistryService) UpsertServeModel(serveModel *openapi.ServeMode serveModel.Name = existing.Name } - execution, err := serv.mapper.MapFromServeModel(serveModel, *parentResourceId) + execution, err := serv.mapper.MapFromServeModel(serveModel, *inferenceServiceId) if err != nil { return nil, err } @@ -1231,8 +1273,8 @@ func (serv *ModelRegistryService) UpsertServeModel(serveModel *openapi.ServeMode } // add explicit Association between ServeModel and InferenceService - if parentResourceId != nil && serveModel.Id == nil { - inferenceServiceId, err := converter.StringToInt64(parentResourceId) + if inferenceServiceId != nil && serveModel.Id == nil { + inferenceServiceId, err := converter.StringToInt64(inferenceServiceId) if err != nil { return nil, err } @@ -1260,6 +1302,7 @@ func (serv *ModelRegistryService) UpsertServeModel(serveModel *openapi.ServeMode return mapped, nil } +// getInferenceServiceByServeModel retrieves the inference service associated with the specified serve model ID. func (serv *ModelRegistryService) getInferenceServiceByServeModel(id string) (*openapi.InferenceService, error) { glog.Infof("Getting InferenceService for ServeModel %s", id) @@ -1291,6 +1334,7 @@ func (serv *ModelRegistryService) getInferenceServiceByServeModel(id string) (*o return toReturn, nil } +// GetServeModelById retrieves a serve model by its unique identifier (ID). func (serv *ModelRegistryService) GetServeModelById(id string) (*openapi.ServeModel, error) { idAsInt, err := converter.StringToInt64(&id) if err != nil { @@ -1320,7 +1364,8 @@ func (serv *ModelRegistryService) GetServeModelById(id string) (*openapi.ServeMo return result, nil } -func (serv *ModelRegistryService) GetServeModels(listOptions api.ListOptions, parentResourceId *string) (*openapi.ServeModelList, error) { +// GetServeModels retrieves a list of serve models based on the provided list options and optional inference service ID. +func (serv *ModelRegistryService) GetServeModels(listOptions api.ListOptions, inferenceServiceId *string) (*openapi.ServeModelList, error) { listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) if err != nil { return nil, err @@ -1328,8 +1373,8 @@ func (serv *ModelRegistryService) GetServeModels(listOptions api.ListOptions, pa var executions []*proto.Execution var nextPageToken *string - if parentResourceId != nil { - ctxId, err := converter.StringToInt64(parentResourceId) + if inferenceServiceId != nil { + ctxId, err := converter.StringToInt64(inferenceServiceId) if err != nil { return nil, err } diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index 5b0bfc5e..c5eeae7b 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -1147,7 +1147,7 @@ func (suite *CoreTestSuite) TestGetModelVersionByParamsWithNoResults() { _, err := service.GetModelVersionByParams(of("not-present"), ®isteredModelId, nil) suite.NotNil(err) - suite.Equal("no model versions found for versionName=not-present, parentResourceId=1, externalId=", err.Error()) + suite.Equal("no model versions found for versionName=not-present, registeredModelId=1, externalId=", err.Error()) } func (suite *CoreTestSuite) TestGetModelVersionByParamsName() { @@ -1238,7 +1238,7 @@ func (suite *CoreTestSuite) TestGetModelVersionByEmptyParams() { _, err = service.GetModelVersionByParams(nil, nil, nil) suite.NotNil(err) - suite.Equal("invalid parameters call, supply either (versionName and parentResourceId), or externalId", err.Error()) + suite.Equal("invalid parameters call, supply either (versionName and registeredModelId), or externalId", err.Error()) } func (suite *CoreTestSuite) TestGetModelVersions() { @@ -1624,7 +1624,7 @@ func (suite *CoreTestSuite) TestGetModelArtifactByEmptyParams() { _, err = service.GetModelArtifactByParams(nil, nil, nil) suite.NotNil(err) - suite.Equal("invalid parameters call, supply either (artifactName and parentResourceId), or externalId", err.Error()) + suite.Equal("invalid parameters call, supply either (artifactName and modelVersionId), or externalId", err.Error()) } func (suite *CoreTestSuite) TestGetModelArtifactByParamsWithNoResults() { @@ -1635,7 +1635,7 @@ func (suite *CoreTestSuite) TestGetModelArtifactByParamsWithNoResults() { _, err := service.GetModelArtifactByParams(of("not-present"), &modelVersionId, nil) suite.NotNil(err) - suite.Equal("no model artifacts found for artifactName=not-present, parentResourceId=2, externalId=", err.Error()) + suite.Equal("no model artifacts found for artifactName=not-present, modelVersionId=2, externalId=", err.Error()) } func (suite *CoreTestSuite) TestGetModelArtifacts() { @@ -2535,7 +2535,7 @@ func (suite *CoreTestSuite) TestGetInferenceServiceByParamsWithNoResults() { _, err := service.GetInferenceServiceByParams(of("not-present"), &parentResourceId, nil) suite.NotNil(err) - suite.Equal("no inference services found for name=not-present, parentResourceId=1, externalId=", err.Error()) + suite.Equal("no inference services found for name=not-present, servingEnvironmentId=1, externalId=", err.Error()) } func (suite *CoreTestSuite) TestGetInferenceServiceByParamsName() { @@ -2657,7 +2657,7 @@ func (suite *CoreTestSuite) TestGetInferenceServiceByEmptyParams() { _, err = service.GetInferenceServiceByParams(nil, nil, nil) suite.NotNil(err) - suite.Equal("invalid parameters call, supply either (name and parentResourceId), or externalId", err.Error()) + suite.Equal("invalid parameters call, supply either (name and servingEnvironmentId), or externalId", err.Error()) } func (suite *CoreTestSuite) TestGetInferenceServices() { @@ -2870,7 +2870,7 @@ func (suite *CoreTestSuite) TestCreateServeModelFailure() { _, err := service.UpsertServeModel(eut, nil) suite.NotNil(err) - suite.Equal("missing parentResourceId, cannot create ServeModel without parent resource InferenceService", err.Error()) + suite.Equal("missing inferenceServiceId, cannot create ServeModel without parent resource InferenceService", err.Error()) _, err = service.UpsertServeModel(eut, &inferenceServiceId) suite.NotNil(err) From 259b39320953bf05942dcec1fb5ec74f7eb5d4a7 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Fri, 1 Dec 2023 12:49:44 +0100 Subject: [PATCH 177/254] py: Fix typo in README.md - server_address - port is numeric (int) - model_format_name - model_format_version - (optional) using example data for Serving --- clients/python/README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index 93575223..1e1199ee 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -10,13 +10,14 @@ This library provides a high level interface for interacting with a model regist ```py from model_registry import ModelRegistry -registry = ModelRegistry(address="server-address", port="port", author="author") +registry = ModelRegistry(server_address="server-address", port=9090, author="author") model = registry.register_model("my-model", "s3://path/to/model", - format_name="onnx", - format_version="v1", - secret_account_name="access", + model_format_name="onnx", + model_format_version="1", + storage_key="aws-connection-path", + storage_path="to/model", version="v2.0", description="lorem ipsum", ) From bd5191d87f097e6be48a9f690afec42f1bfca218 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Mon, 4 Dec 2023 11:08:36 +0100 Subject: [PATCH 178/254] Improve err mgmt when providing wrong entity (#220) * Improve err mgmt when providing wrong entity * Applied suggestions: unspecified behavior when error not nil Signed-off-by: Andrea Lamparelli Co-authored-by: Matteo Mortari --------- Signed-off-by: Andrea Lamparelli Co-authored-by: Matteo Mortari --- internal/constants/constants.go | 11 ++ .../converter/mlmd_converter_util_test.go | 39 +++-- .../converter/mlmd_openapi_converter_util.go | 3 +- internal/converter/openapi_mlmd_converter.go | 9 -- .../converter/openapi_mlmd_converter_util.go | 76 ++++++---- internal/mapper/mapper.go | 63 ++++---- internal/mapper/mapper_test.go | 143 ++++++++++++++++-- pkg/core/core.go | 34 +++-- 8 files changed, 263 insertions(+), 115 deletions(-) create mode 100644 internal/constants/constants.go diff --git a/internal/constants/constants.go b/internal/constants/constants.go new file mode 100644 index 00000000..d218d3fb --- /dev/null +++ b/internal/constants/constants.go @@ -0,0 +1,11 @@ +package constants + +// MLMD type names +const ( + RegisteredModelTypeName = "odh.RegisteredModel" + ModelVersionTypeName = "odh.ModelVersion" + ModelArtifactTypeName = "odh.ModelArtifact" + ServingEnvironmentTypeName = "odh.ServingEnvironment" + InferenceServiceTypeName = "odh.InferenceService" + ServeModelTypeName = "odh.ServeModel" +) diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index 318c4e29..1251da3f 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -6,6 +6,7 @@ import ( "strings" "testing" + "github.com/opendatahub-io/model-registry/internal/constants" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/pkg/openapi" "github.com/stretchr/testify/assert" @@ -207,7 +208,7 @@ func TestMapRegisteredModelType(t *testing.T) { typeName := MapRegisteredModelType(&openapi.RegisteredModel{}) assertion.NotNil(typeName) - assertion.Equal(RegisteredModelTypeName, *typeName) + assertion.Equal(constants.RegisteredModelTypeName, *typeName) } func TestMapModelVersionProperties(t *testing.T) { @@ -235,7 +236,7 @@ func TestMapModelVersionType(t *testing.T) { typeName := MapModelVersionType(&openapi.ModelVersion{}) assertion.NotNil(typeName) - assertion.Equal(ModelVersionTypeName, *typeName) + assertion.Equal(constants.ModelVersionTypeName, *typeName) } func TestMapModelVersionName(t *testing.T) { @@ -286,7 +287,7 @@ func TestMapModelArtifactType(t *testing.T) { typeName := MapModelArtifactType(&openapi.ModelArtifact{}) assertion.NotNil(typeName) - assertion.Equal(ModelArtifactTypeName, *typeName) + assertion.Equal(constants.ModelArtifactTypeName, *typeName) } func TestMapModelArtifactName(t *testing.T) { @@ -517,7 +518,7 @@ func TestMapArtifactType(t *testing.T) { assertion := setup(t) artifactType, err := MapArtifactType(&proto.Artifact{ - Type: of(ModelArtifactTypeName), + Type: of(constants.ModelArtifactTypeName), }) assertion.Nil(err) assertion.Equal("model-artifact", artifactType) @@ -593,7 +594,7 @@ func TestMapServingEnvironmentType(t *testing.T) { typeName := MapServingEnvironmentType(&openapi.ServingEnvironment{}) assertion.NotNil(typeName) - assertion.Equal(ServingEnvironmentTypeName, *typeName) + assertion.Equal(constants.ServingEnvironmentTypeName, *typeName) } func TestMapInferenceServiceType(t *testing.T) { @@ -601,7 +602,7 @@ func TestMapInferenceServiceType(t *testing.T) { typeName := MapInferenceServiceType(&openapi.InferenceService{}) assertion.NotNil(typeName) - assertion.Equal(InferenceServiceTypeName, *typeName) + assertion.Equal(constants.InferenceServiceTypeName, *typeName) } func TestMapInferenceServiceProperties(t *testing.T) { @@ -623,9 +624,18 @@ func TestMapInferenceServiceProperties(t *testing.T) { assertion.Equal(int64(3), props["serving_environment_id"].GetIntValue()) // serving and model id must be provided and must be a valid numeric id - props, err = MapInferenceServiceProperties(&openapi.InferenceService{}) + _, err = MapInferenceServiceProperties(&openapi.InferenceService{}) assertion.NotNil(err) - assertion.Equal(0, len(props)) + assertion.Equal("missing required RegisteredModelId field", err.Error()) + + _, err = MapInferenceServiceProperties(&openapi.InferenceService{RegisteredModelId: "1"}) + assertion.NotNil(err) + assertion.Equal("missing required ServingEnvironmentId field", err.Error()) + + // invalid int + _, err = MapInferenceServiceProperties(&openapi.InferenceService{RegisteredModelId: "aa"}) + assertion.NotNil(err) + assertion.Equal("invalid numeric string: strconv.Atoi: parsing \"aa\": invalid syntax", err.Error()) } func TestMapServeModelType(t *testing.T) { @@ -633,7 +643,7 @@ func TestMapServeModelType(t *testing.T) { typeName := MapServeModelType(&openapi.ServeModel{}) assertion.NotNil(typeName) - assertion.Equal(ServeModelTypeName, *typeName) + assertion.Equal(constants.ServeModelTypeName, *typeName) } func TestMapServeModelProperties(t *testing.T) { @@ -648,10 +658,15 @@ func TestMapServeModelProperties(t *testing.T) { assertion.Equal("my custom description", props["description"].GetStringValue()) assertion.Equal(int64(1), props["model_version_id"].GetIntValue()) - // serving and model id must be provided and must be a valid numeric id - props, err = MapServeModelProperties(&openapi.ServeModel{}) + // model version id must be provided + _, err = MapServeModelProperties(&openapi.ServeModel{}) assertion.NotNil(err) - assertion.Equal(0, len(props)) + assertion.Equal("missing required ModelVersionId field", err.Error()) + + // model version id must be a valid numeric + _, err = MapServeModelProperties(&openapi.ServeModel{ModelVersionId: "bb"}) + assertion.NotNil(err) + assertion.Equal("invalid numeric string: strconv.Atoi: parsing \"bb\": invalid syntax", err.Error()) } func TestMapServingEnvironmentProperties(t *testing.T) { diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 11bdf016..6e0539d7 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" + "github.com/opendatahub-io/model-registry/internal/constants" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/pkg/openapi" ) @@ -82,7 +83,7 @@ func MapPropertyAuthor(properties map[string]*proto.Value) *string { // MODEL ARTIFACT func MapArtifactType(source *proto.Artifact) (string, error) { - if source.Type != nil && *source.Type == ModelArtifactTypeName { + if source.Type != nil && *source.Type == constants.ModelArtifactTypeName { return "model-artifact", nil } return "", fmt.Errorf("invalid artifact type found: %v", source.Type) diff --git a/internal/converter/openapi_mlmd_converter.go b/internal/converter/openapi_mlmd_converter.go index 3db5be72..5d58c3da 100644 --- a/internal/converter/openapi_mlmd_converter.go +++ b/internal/converter/openapi_mlmd_converter.go @@ -5,15 +5,6 @@ import ( "github.com/opendatahub-io/model-registry/pkg/openapi" ) -const ( - RegisteredModelTypeName = "odh.RegisteredModel" - ModelVersionTypeName = "odh.ModelVersion" - ModelArtifactTypeName = "odh.ModelArtifact" - ServingEnvironmentTypeName = "odh.ServingEnvironment" - InferenceServiceTypeName = "odh.InferenceService" - ServeModelTypeName = "odh.ServeModel" -) - type OpenAPIModelWrapper[ M openapi.RegisteredModel | openapi.ModelVersion | diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index e33dfa48..97fb3c8c 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -7,6 +7,7 @@ import ( "strconv" "github.com/google/uuid" + "github.com/opendatahub-io/model-registry/internal/constants" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" "github.com/opendatahub-io/model-registry/pkg/openapi" "google.golang.org/protobuf/types/known/structpb" @@ -20,7 +21,7 @@ func StringToInt64(id *string) (*int64, error) { idAsInt, err := strconv.Atoi(*id) if err != nil { - return nil, err + return nil, fmt.Errorf("invalid numeric string: %v", err) } idInt64 := int64(idAsInt) @@ -143,7 +144,7 @@ func MapRegisteredModelProperties(source *openapi.RegisteredModel) (map[string]* // MapRegisteredModelType return RegisteredModel corresponding MLMD context type func MapRegisteredModelType(_ *openapi.RegisteredModel) *string { - return of(RegisteredModelTypeName) + return of(constants.RegisteredModelTypeName) } // MODEL VERSION @@ -193,7 +194,7 @@ func MapModelVersionProperties(source *OpenAPIModelWrapper[openapi.ModelVersion] // MapModelVersionType return ModelVersion corresponding MLMD context type func MapModelVersionType(_ *openapi.ModelVersion) *string { - return of(ModelVersionTypeName) + return of(constants.ModelVersionTypeName) } // MapModelVersionName maps the user-provided name into MLMD one, i.e., prefixing it with @@ -256,7 +257,7 @@ func MapModelArtifactProperties(source *openapi.ModelArtifact) (map[string]*prot // MapModelArtifactType return ModelArtifact corresponding MLMD context type func MapModelArtifactType(_ *openapi.ModelArtifact) *string { - return of(ModelArtifactTypeName) + return of(constants.ModelArtifactTypeName) } // MapModelArtifactName maps the user-provided name into MLMD one, i.e., prefixing it with @@ -290,7 +291,7 @@ func MapOpenAPIModelArtifactState(source *openapi.ArtifactState) (*proto.Artifac // MapServingEnvironmentType return ServingEnvironment corresponding MLMD context type func MapServingEnvironmentType(_ *openapi.ServingEnvironment) *string { - return of(ServingEnvironmentTypeName) + return of(constants.ServingEnvironmentTypeName) } // MapServingEnvironmentProperties maps ServingEnvironment fields to specific MLMD properties @@ -312,7 +313,7 @@ func MapServingEnvironmentProperties(source *openapi.ServingEnvironment) (map[st // MapInferenceServiceType return InferenceService corresponding MLMD context type func MapInferenceServiceType(_ *openapi.InferenceService) *string { - return of(InferenceServiceTypeName) + return of(constants.InferenceServiceTypeName) } // MapInferenceServiceProperties maps InferenceService fields to specific MLMD properties @@ -343,24 +344,32 @@ func MapInferenceServiceProperties(source *openapi.InferenceService) (map[string } } - registeredModelId, err := StringToInt64(&source.RegisteredModelId) - if err != nil { - return nil, err - } - props["registered_model_id"] = &proto.Value{ - Value: &proto.Value_IntValue{ - IntValue: *registeredModelId, - }, + if source.RegisteredModelId != "" { + registeredModelId, err := StringToInt64(&source.RegisteredModelId) + if err != nil { + return nil, err + } + props["registered_model_id"] = &proto.Value{ + Value: &proto.Value_IntValue{ + IntValue: *registeredModelId, + }, + } + } else { + return nil, fmt.Errorf("missing required RegisteredModelId field") } - servingEnvironmentId, err := StringToInt64(&source.ServingEnvironmentId) - if err != nil { - return nil, err - } - props["serving_environment_id"] = &proto.Value{ - Value: &proto.Value_IntValue{ - IntValue: *servingEnvironmentId, - }, + if source.ServingEnvironmentId != "" { + servingEnvironmentId, err := StringToInt64(&source.ServingEnvironmentId) + if err != nil { + return nil, err + } + props["serving_environment_id"] = &proto.Value{ + Value: &proto.Value_IntValue{ + IntValue: *servingEnvironmentId, + }, + } + } else { + return nil, fmt.Errorf("missing required ServingEnvironmentId field") } if source.ModelVersionId != nil { @@ -390,7 +399,7 @@ func MapInferenceServiceName(source *OpenAPIModelWrapper[openapi.InferenceServic // MapServeModelType return ServeModel corresponding MLMD context type func MapServeModelType(_ *openapi.ServeModel) *string { - return of(ServeModelTypeName) + return of(constants.ServeModelTypeName) } // MapServeModelProperties maps ServeModel fields to specific MLMD properties @@ -405,16 +414,19 @@ func MapServeModelProperties(source *openapi.ServeModel) (map[string]*proto.Valu } } - modelVersionId, err := StringToInt64(&source.ModelVersionId) - if err != nil { - return nil, err - } - props["model_version_id"] = &proto.Value{ - Value: &proto.Value_IntValue{ - IntValue: *modelVersionId, - }, + if source.ModelVersionId != "" { + modelVersionId, err := StringToInt64(&source.ModelVersionId) + if err != nil { + return nil, err + } + props["model_version_id"] = &proto.Value{ + Value: &proto.Value_IntValue{ + IntValue: *modelVersionId, + }, + } + } else { + return nil, fmt.Errorf("missing required ModelVersionId field") } - } return props, nil } diff --git a/internal/mapper/mapper.go b/internal/mapper/mapper.go index caccefef..6ac31b5f 100644 --- a/internal/mapper/mapper.go +++ b/internal/mapper/mapper.go @@ -3,6 +3,7 @@ package mapper import ( "fmt" + "github.com/opendatahub-io/model-registry/internal/constants" "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/converter/generated" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" @@ -10,26 +11,16 @@ import ( ) type Mapper struct { - OpenAPIConverter converter.OpenAPIToMLMDConverter - MLMDConverter converter.MLMDToOpenAPIConverter - RegisteredModelTypeId int64 - ModelVersionTypeId int64 - ModelArtifactTypeId int64 - ServingEnvironmentTypeId int64 - InferenceServiceTypeId int64 - ServeModelTypeId int64 + OpenAPIConverter converter.OpenAPIToMLMDConverter + MLMDConverter converter.MLMDToOpenAPIConverter + MLMDTypes map[string]int64 } -func NewMapper(registeredModelTypeId int64, modelVersionTypeId int64, modelArtifactTypeId int64, servingEnvironmentTypeId int64, inferenceServiceTypeId int64, serveModelTypeId int64) *Mapper { +func NewMapper(mlmdTypes map[string]int64) *Mapper { return &Mapper{ - OpenAPIConverter: &generated.OpenAPIToMLMDConverterImpl{}, - MLMDConverter: &generated.MLMDToOpenAPIConverterImpl{}, - RegisteredModelTypeId: registeredModelTypeId, - ModelVersionTypeId: modelVersionTypeId, - ModelArtifactTypeId: modelArtifactTypeId, - ServingEnvironmentTypeId: servingEnvironmentTypeId, - InferenceServiceTypeId: inferenceServiceTypeId, - ServeModelTypeId: serveModelTypeId, + OpenAPIConverter: &generated.OpenAPIToMLMDConverterImpl{}, + MLMDConverter: &generated.MLMDToOpenAPIConverterImpl{}, + MLMDTypes: mlmdTypes, } } @@ -37,7 +28,7 @@ func NewMapper(registeredModelTypeId int64, modelVersionTypeId int64, modelArtif func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel) (*proto.Context, error) { ctx, err := m.OpenAPIConverter.ConvertRegisteredModel(&converter.OpenAPIModelWrapper[openapi.RegisteredModel]{ - TypeId: m.RegisteredModelTypeId, + TypeId: m.MLMDTypes[constants.RegisteredModelTypeName], Model: registeredModel, }) if err != nil { @@ -49,7 +40,7 @@ func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registeredModelId string, registeredModelName *string) (*proto.Context, error) { ctx, err := m.OpenAPIConverter.ConvertModelVersion(&converter.OpenAPIModelWrapper[openapi.ModelVersion]{ - TypeId: m.ModelVersionTypeId, + TypeId: m.MLMDTypes[constants.ModelVersionTypeName], Model: modelVersion, ParentResourceId: ®isteredModelId, ModelName: registeredModelName, @@ -64,7 +55,7 @@ func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registe func (m *Mapper) MapFromModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *string) (*proto.Artifact, error) { artifact, err := m.OpenAPIConverter.ConvertModelArtifact(&converter.OpenAPIModelWrapper[openapi.ModelArtifact]{ - TypeId: m.ModelArtifactTypeId, + TypeId: m.MLMDTypes[constants.ModelArtifactTypeName], Model: modelArtifact, ParentResourceId: modelVersionId, }) @@ -75,12 +66,12 @@ func (m *Mapper) MapFromModelArtifact(modelArtifact *openapi.ModelArtifact, mode return artifact, nil } -func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact, modelVersionId *string) ([]*proto.Artifact, error) { +func (m *Mapper) MapFromModelArtifacts(modelArtifacts []openapi.ModelArtifact, modelVersionId *string) ([]*proto.Artifact, error) { artifacts := []*proto.Artifact{} if modelArtifacts == nil { return artifacts, nil } - for _, a := range *modelArtifacts { + for _, a := range modelArtifacts { mapped, err := m.MapFromModelArtifact(&a, modelVersionId) if err != nil { return nil, err @@ -92,7 +83,7 @@ func (m *Mapper) MapFromModelArtifacts(modelArtifacts *[]openapi.ModelArtifact, func (m *Mapper) MapFromServingEnvironment(servingEnvironment *openapi.ServingEnvironment) (*proto.Context, error) { ctx, err := m.OpenAPIConverter.ConvertServingEnvironment(&converter.OpenAPIModelWrapper[openapi.ServingEnvironment]{ - TypeId: m.ServingEnvironmentTypeId, + TypeId: m.MLMDTypes[constants.ServingEnvironmentTypeName], Model: servingEnvironment, }) if err != nil { @@ -104,7 +95,7 @@ func (m *Mapper) MapFromServingEnvironment(servingEnvironment *openapi.ServingEn func (m *Mapper) MapFromInferenceService(inferenceService *openapi.InferenceService, servingEnvironmentId string) (*proto.Context, error) { ctx, err := m.OpenAPIConverter.ConvertInferenceService(&converter.OpenAPIModelWrapper[openapi.InferenceService]{ - TypeId: m.InferenceServiceTypeId, + TypeId: m.MLMDTypes[constants.InferenceServiceTypeName], Model: inferenceService, ParentResourceId: &servingEnvironmentId, }) @@ -117,7 +108,7 @@ func (m *Mapper) MapFromInferenceService(inferenceService *openapi.InferenceServ func (m *Mapper) MapFromServeModel(serveModel *openapi.ServeModel, inferenceServiceId string) (*proto.Execution, error) { ctx, err := m.OpenAPIConverter.ConvertServeModel(&converter.OpenAPIModelWrapper[openapi.ServeModel]{ - TypeId: m.ServeModelTypeId, + TypeId: m.MLMDTypes[constants.ServeModelTypeName], Model: serveModel, ParentResourceId: &inferenceServiceId, }) @@ -131,36 +122,42 @@ func (m *Mapper) MapFromServeModel(serveModel *openapi.ServeModel, inferenceServ // Utilities for MLMD --> OpenAPI mapping, make use of generated Converters func (m *Mapper) MapToRegisteredModel(ctx *proto.Context) (*openapi.RegisteredModel, error) { - return mapTo(ctx, m.RegisteredModelTypeId, m.MLMDConverter.ConvertRegisteredModel) + return mapTo(ctx, m.MLMDTypes, constants.RegisteredModelTypeName, m.MLMDConverter.ConvertRegisteredModel) } func (m *Mapper) MapToModelVersion(ctx *proto.Context) (*openapi.ModelVersion, error) { - return mapTo(ctx, m.ModelVersionTypeId, m.MLMDConverter.ConvertModelVersion) + return mapTo(ctx, m.MLMDTypes, constants.ModelVersionTypeName, m.MLMDConverter.ConvertModelVersion) } func (m *Mapper) MapToModelArtifact(art *proto.Artifact) (*openapi.ModelArtifact, error) { - return mapTo(art, m.ModelArtifactTypeId, m.MLMDConverter.ConvertModelArtifact) + return mapTo(art, m.MLMDTypes, constants.ModelArtifactTypeName, m.MLMDConverter.ConvertModelArtifact) } func (m *Mapper) MapToServingEnvironment(ctx *proto.Context) (*openapi.ServingEnvironment, error) { - return mapTo(ctx, m.ServingEnvironmentTypeId, m.MLMDConverter.ConvertServingEnvironment) + return mapTo(ctx, m.MLMDTypes, constants.ServingEnvironmentTypeName, m.MLMDConverter.ConvertServingEnvironment) } func (m *Mapper) MapToInferenceService(ctx *proto.Context) (*openapi.InferenceService, error) { - return mapTo(ctx, m.InferenceServiceTypeId, m.MLMDConverter.ConvertInferenceService) + return mapTo(ctx, m.MLMDTypes, constants.InferenceServiceTypeName, m.MLMDConverter.ConvertInferenceService) } func (m *Mapper) MapToServeModel(ex *proto.Execution) (*openapi.ServeModel, error) { - return mapTo(ex, m.ServeModelTypeId, m.MLMDConverter.ConvertServeModel) + return mapTo(ex, m.MLMDTypes, constants.ServeModelTypeName, m.MLMDConverter.ConvertServeModel) } type getTypeIder interface { GetTypeId() int64 + GetType() string } -func mapTo[S getTypeIder, T any](s S, id int64, convFn func(S) (*T, error)) (*T, error) { +func mapTo[S getTypeIder, T any](s S, typesMap map[string]int64, typeName string, convFn func(S) (*T, error)) (*T, error) { + id, ok := typesMap[typeName] + if !ok { + return nil, fmt.Errorf("unknown type name provided: %s", typeName) + } + if s.GetTypeId() != id { - return nil, fmt.Errorf("invalid TypeId, expected %d but received %d", id, s.GetTypeId()) + return nil, fmt.Errorf("invalid entity: expected %s but received %s, please check the provided id", typeName, s.GetType()) } return convFn(s) } diff --git a/internal/mapper/mapper_test.go b/internal/mapper/mapper_test.go index 4174ff84..4996e14c 100644 --- a/internal/mapper/mapper_test.go +++ b/internal/mapper/mapper_test.go @@ -4,7 +4,9 @@ import ( "fmt" "testing" + "github.com/opendatahub-io/model-registry/internal/constants" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/pkg/openapi" "github.com/stretchr/testify/assert" ) @@ -18,21 +20,120 @@ const ( serveModelTypeId = int64(6) ) +var typesMap = map[string]int64{ + constants.RegisteredModelTypeName: registeredModelTypeId, + constants.ModelVersionTypeName: modelVersionTypeId, + constants.ModelArtifactTypeName: modelArtifactTypeId, + constants.ServingEnvironmentTypeName: servingEnvironmentTypeId, + constants.InferenceServiceTypeName: inferenceServiceTypeId, + constants.ServeModelTypeName: serveModelTypeId, +} + func setup(t *testing.T) (*assert.Assertions, *Mapper) { return assert.New(t), NewMapper( - registeredModelTypeId, - modelVersionTypeId, - modelArtifactTypeId, - servingEnvironmentTypeId, - inferenceServiceTypeId, - serveModelTypeId, + typesMap, ) } +func TestMapFromRegisteredModel(t *testing.T) { + assertion, m := setup(t) + + ctx, err := m.MapFromRegisteredModel(&openapi.RegisteredModel{Name: of("ModelName")}) + assertion.Nil(err) + assertion.Equal("ModelName", ctx.GetName()) + assertion.Equal(registeredModelTypeId, ctx.GetTypeId()) +} + +func TestMapFromModelVersion(t *testing.T) { + assertion, m := setup(t) + + ctx, err := m.MapFromModelVersion(&openapi.ModelVersion{Name: of("v1")}, "1", of("ModelName")) + assertion.Nil(err) + assertion.Equal("1:v1", ctx.GetName()) + assertion.Equal(modelVersionTypeId, ctx.GetTypeId()) +} + +func TestMapFromModelArtifact(t *testing.T) { + assertion, m := setup(t) + + ctx, err := m.MapFromModelArtifact(&openapi.ModelArtifact{Name: of("ModelArtifact")}, of("2")) + assertion.Nil(err) + assertion.Equal("2:ModelArtifact", ctx.GetName()) + assertion.Equal(modelArtifactTypeId, ctx.GetTypeId()) +} + +func TestMapFromModelArtifacts(t *testing.T) { + assertion, m := setup(t) + + ctxList, err := m.MapFromModelArtifacts([]openapi.ModelArtifact{{Name: of("ModelArtifact1")}, {Name: of("ModelArtifact2")}}, of("2")) + assertion.Nil(err) + assertion.Equal(2, len(ctxList)) + assertion.Equal("2:ModelArtifact1", ctxList[0].GetName()) + assertion.Equal("2:ModelArtifact2", ctxList[1].GetName()) + assertion.Equal(modelArtifactTypeId, ctxList[0].GetTypeId()) + assertion.Equal(modelArtifactTypeId, ctxList[1].GetTypeId()) +} + +func TestMapFromModelArtifactsEmpty(t *testing.T) { + assertion, m := setup(t) + + ctxList, err := m.MapFromModelArtifacts([]openapi.ModelArtifact{}, of("2")) + assertion.Nil(err) + assertion.Equal(0, len(ctxList)) + + ctxList, err = m.MapFromModelArtifacts(nil, nil) + assertion.Nil(err) + assertion.Equal(0, len(ctxList)) +} + +func TestMapFromServingEnvironment(t *testing.T) { + assertion, m := setup(t) + + ctx, err := m.MapFromServingEnvironment(&openapi.ServingEnvironment{Name: of("Env")}) + assertion.Nil(err) + assertion.Equal("Env", ctx.GetName()) + assertion.Equal(servingEnvironmentTypeId, ctx.GetTypeId()) +} + +func TestMapFromInferenceService(t *testing.T) { + assertion, m := setup(t) + + ctx, err := m.MapFromInferenceService(&openapi.InferenceService{Name: of("IS"), ServingEnvironmentId: "5", RegisteredModelId: "1"}, "5") + assertion.Nil(err) + assertion.Equal("5:IS", ctx.GetName()) + assertion.Equal(inferenceServiceTypeId, ctx.GetTypeId()) +} + +func TestMapFromInferenceServiceMissingRequiredIds(t *testing.T) { + assertion, m := setup(t) + + _, err := m.MapFromInferenceService(&openapi.InferenceService{Name: of("IS")}, "5") + assertion.NotNil(err) + assertion.Equal("error setting field Properties: missing required RegisteredModelId field", err.Error()) +} + +func TestMapFromServeModel(t *testing.T) { + assertion, m := setup(t) + + ctx, err := m.MapFromServeModel(&openapi.ServeModel{Name: of("Serve"), ModelVersionId: "1"}, "10") + assertion.Nil(err) + assertion.Equal("10:Serve", ctx.GetName()) + assertion.Equal(serveModelTypeId, ctx.GetTypeId()) +} + +func TestMapFromServeModelMissingRequiredId(t *testing.T) { + assertion, m := setup(t) + + _, err := m.MapFromServeModel(&openapi.ServeModel{Name: of("Serve")}, "10") + assertion.NotNil(err) + assertion.Equal("error setting field Properties: missing required ModelVersionId field", err.Error()) +} + func TestMapToRegisteredModel(t *testing.T) { assertion, m := setup(t) _, err := m.MapToRegisteredModel(&proto.Context{ TypeId: of(registeredModelTypeId), + Type: of(constants.RegisteredModelTypeName), }) assertion.Nil(err) } @@ -41,15 +142,17 @@ func TestMapToRegisteredModelInvalid(t *testing.T) { assertion, m := setup(t) _, err := m.MapToRegisteredModel(&proto.Context{ TypeId: of(invalidTypeId), + Type: of("odh.OtherEntity"), }) assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", registeredModelTypeId, invalidTypeId), err.Error()) + assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.RegisteredModelTypeName), err.Error()) } func TestMapToModelVersion(t *testing.T) { assertion, m := setup(t) _, err := m.MapToModelVersion(&proto.Context{ TypeId: of(modelVersionTypeId), + Type: of(constants.ModelVersionTypeName), }) assertion.Nil(err) } @@ -58,16 +161,17 @@ func TestMapToModelVersionInvalid(t *testing.T) { assertion, m := setup(t) _, err := m.MapToModelVersion(&proto.Context{ TypeId: of(invalidTypeId), + Type: of("odh.OtherEntity"), }) assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", modelVersionTypeId, invalidTypeId), err.Error()) + assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.ModelVersionTypeName), err.Error()) } func TestMapToModelArtifact(t *testing.T) { assertion, m := setup(t) _, err := m.MapToModelArtifact(&proto.Artifact{ TypeId: of(modelArtifactTypeId), - Type: of("odh.ModelArtifact"), + Type: of(constants.ModelArtifactTypeName), }) assertion.Nil(err) } @@ -85,15 +189,17 @@ func TestMapToModelArtifactInvalid(t *testing.T) { assertion, m := setup(t) _, err := m.MapToModelArtifact(&proto.Artifact{ TypeId: of(invalidTypeId), + Type: of("odh.OtherEntity"), }) assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", modelArtifactTypeId, invalidTypeId), err.Error()) + assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.ModelArtifactTypeName), err.Error()) } func TestMapToServingEnvironment(t *testing.T) { assertion, m := setup(t) _, err := m.MapToServingEnvironment(&proto.Context{ TypeId: of(servingEnvironmentTypeId), + Type: of(constants.ServingEnvironmentTypeName), }) assertion.Nil(err) } @@ -102,15 +208,17 @@ func TestMapToServingEnvironmentInvalid(t *testing.T) { assertion, m := setup(t) _, err := m.MapToServingEnvironment(&proto.Context{ TypeId: of(invalidTypeId), + Type: of("odh.OtherEntity"), }) assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", servingEnvironmentTypeId, invalidTypeId), err.Error()) + assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.ServingEnvironmentTypeName), err.Error()) } func TestMapToInferenceService(t *testing.T) { assertion, m := setup(t) _, err := m.MapToInferenceService(&proto.Context{ TypeId: of(inferenceServiceTypeId), + Type: of(constants.InferenceServiceTypeName), }) assertion.Nil(err) } @@ -119,15 +227,17 @@ func TestMapToInferenceServiceInvalid(t *testing.T) { assertion, m := setup(t) _, err := m.MapToInferenceService(&proto.Context{ TypeId: of(invalidTypeId), + Type: of("odh.OtherEntity"), }) assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", inferenceServiceTypeId, invalidTypeId), err.Error()) + assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.InferenceServiceTypeName), err.Error()) } func TestMapToServeModel(t *testing.T) { assertion, m := setup(t) _, err := m.MapToServeModel(&proto.Execution{ TypeId: of(serveModelTypeId), + Type: of(constants.ServeModelTypeName), }) assertion.Nil(err) } @@ -136,9 +246,16 @@ func TestMapToServeModelInvalid(t *testing.T) { assertion, m := setup(t) _, err := m.MapToServeModel(&proto.Execution{ TypeId: of(invalidTypeId), + Type: of("odh.OtherEntity"), }) assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("invalid TypeId, expected %d but received %d", serveModelTypeId, invalidTypeId), err.Error()) + assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.ServeModelTypeName), err.Error()) +} + +func TestMapTo(t *testing.T) { + _, err := mapTo[*proto.Execution, any](&proto.Execution{TypeId: of(registeredModelTypeId)}, typesMap, "notExisitingTypeName", func(e *proto.Execution) (*any, error) { return nil, nil }) + assert.NotNil(t, err) + assert.Equal(t, "unknown type name provided: notExisitingTypeName", err.Error()) } // of returns a pointer to the provided literal/const input diff --git a/pkg/core/core.go b/pkg/core/core.go index 3b36833e..9dc9d084 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -7,6 +7,7 @@ import ( "github.com/golang/glog" "github.com/opendatahub-io/model-registry/internal/apiutils" + "github.com/opendatahub-io/model-registry/internal/constants" "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/converter/generated" "github.com/opendatahub-io/model-registry/internal/mapper" @@ -17,18 +18,19 @@ import ( ) var ( - registeredModelTypeName = of(converter.RegisteredModelTypeName) - modelVersionTypeName = of(converter.ModelVersionTypeName) - modelArtifactTypeName = of(converter.ModelArtifactTypeName) - servingEnvironmentTypeName = of(converter.ServingEnvironmentTypeName) - inferenceServiceTypeName = of(converter.InferenceServiceTypeName) - serveModelTypeName = of(converter.ServeModelTypeName) + registeredModelTypeName = of(constants.RegisteredModelTypeName) + modelVersionTypeName = of(constants.ModelVersionTypeName) + modelArtifactTypeName = of(constants.ModelArtifactTypeName) + servingEnvironmentTypeName = of(constants.ServingEnvironmentTypeName) + inferenceServiceTypeName = of(constants.InferenceServiceTypeName) + serveModelTypeName = of(constants.ServeModelTypeName) canAddFields = of(true) ) // ModelRegistryService is the core library of the model registry type ModelRegistryService struct { mlmdClient proto.MetadataStoreServiceClient + typesMap map[string]int64 mapper *mapper.Mapper openapiConv *generated.OpenAPIConverterImpl } @@ -151,17 +153,19 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, return nil, fmt.Errorf("error setting up execution type %s: %v", *serveModelTypeName, err) } + typesMap := map[string]int64{ + constants.RegisteredModelTypeName: registeredModelResp.GetTypeId(), + constants.ModelVersionTypeName: modelVersionResp.GetTypeId(), + constants.ModelArtifactTypeName: modelArtifactResp.GetTypeId(), + constants.ServingEnvironmentTypeName: servingEnvironmentResp.GetTypeId(), + constants.InferenceServiceTypeName: inferenceServiceResp.GetTypeId(), + constants.ServeModelTypeName: serveModelResp.GetTypeId(), + } return &ModelRegistryService{ - mlmdClient: client, - mapper: mapper.NewMapper( - registeredModelResp.GetTypeId(), - modelVersionResp.GetTypeId(), - modelArtifactResp.GetTypeId(), - servingEnvironmentResp.GetTypeId(), - inferenceServiceResp.GetTypeId(), - serveModelResp.GetTypeId(), - ), + mlmdClient: client, + typesMap: typesMap, openapiConv: &generated.OpenAPIConverterImpl{}, + mapper: mapper.NewMapper(typesMap), }, nil } From 0621864cea0d438df528afd1aac0bd6eb39fc0c2 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Fri, 1 Dec 2023 16:25:32 -0300 Subject: [PATCH 179/254] py: types: add state property to contexts Closes: #186 Signed-off-by: Isabella Basso do Amaral --- .../src/model_registry/types/__init__.py | 3 +- .../src/model_registry/types/artifacts.py | 2 +- .../src/model_registry/types/contexts.py | 31 +++++++++++++++++++ clients/python/tests/conftest.py | 2 ++ clients/python/tests/test_core.py | 2 ++ .../tests/types/test_context_mapping.py | 27 +++++++++------- 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/clients/python/src/model_registry/types/__init__.py b/clients/python/src/model_registry/types/__init__.py index 8f3e3cde..722dc9d1 100644 --- a/clients/python/src/model_registry/types/__init__.py +++ b/clients/python/src/model_registry/types/__init__.py @@ -4,7 +4,7 @@ """ from .artifacts import ArtifactState, ModelArtifact -from .contexts import ModelVersion, RegisteredModel +from .contexts import ContextState, ModelVersion, RegisteredModel from .options import ListOptions, OrderByField __all__ = [ @@ -14,6 +14,7 @@ # Contexts "ModelVersion", "RegisteredModel", + "ContextState", # Options "ListOptions", "OrderByField", diff --git a/clients/python/src/model_registry/types/artifacts.py b/clients/python/src/model_registry/types/artifacts.py index b4c4a699..da7c2799 100644 --- a/clients/python/src/model_registry/types/artifacts.py +++ b/clients/python/src/model_registry/types/artifacts.py @@ -58,7 +58,7 @@ def get_proto_type(cls) -> type[Artifact]: def map(self, type_id: int) -> Artifact: mlmd_obj = super().map(type_id) mlmd_obj.uri = self.uri - mlmd_obj.state = ArtifactState[self.state.name].value + mlmd_obj.state = self.state.value return mlmd_obj @classmethod diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 2a8a5d32..6b452ae9 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -12,6 +12,7 @@ from __future__ import annotations from abc import ABC +from enum import Enum, unique from attrs import define, field from ml_metadata.proto import Context @@ -23,10 +24,40 @@ from .base import Prefixable, ProtoBase +@unique +class ContextState(Enum): + """State of the context. + + LIVE: The context is live and can be used. + ARCHIVED: The context is archived and can't be used. + """ + + LIVE = "LIVE" + ARCHIVED = "ARCHIVED" + + @define(slots=False, init=False) class BaseContext(ProtoBase, ABC): """Abstract base class for all contexts.""" + state: ContextState = field(init=False, default=ContextState.LIVE) + + @override + def map(self, type_id: int) -> Context: + mlmd_obj = super().map(type_id) + mlmd_obj.properties["state"].string_value = self.state.value + return mlmd_obj + + @classmethod + @override + def unmap(cls, mlmd_obj: Context) -> BaseContext: + py_obj = super().unmap(mlmd_obj) + assert isinstance( + py_obj, BaseContext + ), f"Expected BaseContext, got {type(py_obj)}" + py_obj.state = ContextState(mlmd_obj.properties["state"].string_value) + return py_obj + @classmethod @override def get_proto_type(cls) -> type[Context]: diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py index 24add635..d45d65ba 100644 --- a/clients/python/tests/conftest.py +++ b/clients/python/tests/conftest.py @@ -52,6 +52,7 @@ def store_wrapper(plain_wrapper: MLMDStore) -> MLMDStore: "author", "description", "model_name", + "state", "tags", ], ) @@ -63,6 +64,7 @@ def store_wrapper(plain_wrapper: MLMDStore) -> MLMDStore: RegisteredModel.get_proto_type_name(), [ "description", + "state", ], ) diff --git a/clients/python/tests/test_core.py b/clients/python/tests/test_core.py index b35d7e8e..f509107d 100644 --- a/clients/python/tests/test_core.py +++ b/clients/python/tests/test_core.py @@ -38,6 +38,7 @@ def model_version(store_wrapper: MLMDStore, model: Mapped) -> Mapped: ctx.type_id = store_wrapper.get_type_id(Context, ModelVersion.get_proto_type_name()) ctx.properties["author"].string_value = "author" ctx.properties["model_name"].string_value = model.py.name + ctx.properties["state"].string_value = "LIVE" return Mapped(ctx, ModelVersion(model.py.name, "version", "author")) @@ -49,6 +50,7 @@ def registered_model(store_wrapper: MLMDStore, model: Mapped) -> Mapped: ctx.type_id = store_wrapper.get_type_id( Context, RegisteredModel.get_proto_type_name() ) + ctx.properties["state"].string_value = "LIVE" return Mapped(ctx, RegisteredModel(model.py.name)) diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index 14762a56..5d01b0e9 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -6,7 +6,7 @@ import pytest from ml_metadata.proto import Context -from model_registry.types import ModelVersion +from model_registry.types import ContextState, ModelVersion from .. import Mapped @@ -21,6 +21,7 @@ def full_model_version() -> Mapped: proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" proto_version.properties["tags"].string_value = "test_tag1,test_tag2" + proto_version.properties["state"].string_value = "ARCHIVED" proto_version.custom_properties["int_key"].int_value = 1 proto_version.custom_properties["float_key"].double_value = 1.0 proto_version.custom_properties["bool_key"].bool_value = True @@ -41,6 +42,7 @@ def full_model_version() -> Mapped: "bool_key": True, "str_key": "test_str", } + py_version.state = ContextState.ARCHIVED return Mapped(proto_version, py_version) @@ -51,6 +53,7 @@ def minimal_model_version() -> Mapped: proto_version.type_id = 2 proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" + proto_version.properties["state"].string_value = "LIVE" py_version = ModelVersion("test_model", "1.0.0", "test_author") py_version._registered_model_id = 1 @@ -65,26 +68,27 @@ def test_partial_model_version_mapping(minimal_model_version: Mapped): assert mapped_version.properties == proto_version.properties -def test_full_model_version_mapping(full_model_version: Mapped): - mapped_version = full_model_version.py.map(2) - proto_version = full_model_version.proto - assert mapped_version.name == proto_version.name - assert mapped_version.type_id == proto_version.type_id - assert mapped_version.external_id == proto_version.external_id - assert mapped_version.properties == proto_version.properties - assert mapped_version.custom_properties == proto_version.custom_properties - - def test_partial_model_version_unmapping(minimal_model_version: Mapped): unmapped_version = ModelVersion.unmap(minimal_model_version.proto) py_version = minimal_model_version.py assert unmapped_version.version == py_version.version assert unmapped_version.model_name == py_version.model_name assert unmapped_version.author == py_version.author + assert unmapped_version.state == py_version.state assert unmapped_version.tags == py_version.tags assert unmapped_version.metadata == py_version.metadata +def test_full_model_version_mapping(full_model_version: Mapped): + mapped_version = full_model_version.py.map(2) + proto_version = full_model_version.proto + assert mapped_version.name == proto_version.name + assert mapped_version.type_id == proto_version.type_id + assert mapped_version.external_id == proto_version.external_id + assert mapped_version.properties == proto_version.properties + assert mapped_version.custom_properties == proto_version.custom_properties + + def test_full_model_version_unmapping(full_model_version: Mapped): unmapped_version = ModelVersion.unmap(full_model_version.proto) py_version = full_model_version.py @@ -93,5 +97,6 @@ def test_full_model_version_unmapping(full_model_version: Mapped): assert unmapped_version.external_id == py_version.external_id assert unmapped_version.model_name == py_version.model_name assert unmapped_version.author == py_version.author + assert unmapped_version.state == py_version.state assert unmapped_version.tags == py_version.tags assert unmapped_version.metadata == py_version.metadata From da35fd3bed2deb80d182d3fcae1dc63e074363b1 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 5 Dec 2023 17:42:06 -0300 Subject: [PATCH 180/254] py: noxfile: lint entire project Signed-off-by: Isabella Basso do Amaral --- clients/python/noxfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py index 567ff348..2e9bb70d 100644 --- a/clients/python/noxfile.py +++ b/clients/python/noxfile.py @@ -33,7 +33,7 @@ def lint(session: Session) -> None: """Lint using ruff.""" session.install("ruff") - session.run("ruff", "check", "src") + session.run("ruff", "check", ".") @session(python=python_versions) From 8ee2d82389afb7d1d3b8176012675c3ce2d16aa5 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Mon, 11 Dec 2023 15:39:00 +0100 Subject: [PATCH 181/254] Document helpful tips for dev on Apple-silicon/ARM (#215) * Document helpful tips for dev on Apple-silicon/ARM * implement code review changes --- CONTRIBUTING.md | 181 ++++++++++++++++++++++ doc/Screenshot 2023-11-29 at 14.08.12.png | Bin 0 -> 345093 bytes doc/Screenshot 2023-11-29 at 14.10.14.png | Bin 0 -> 442892 bytes 3 files changed, 181 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 doc/Screenshot 2023-11-29 at 14.08.12.png create mode 100644 doc/Screenshot 2023-11-29 at 14.10.14.png diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..faab737a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,181 @@ +Make reference to ODH Community contribution document: https://github.com/opendatahub-io/opendatahub-community/blob/main/contributing.md + +
+ +This document focus on technical aspects while contributing to the Model Registry project + +# Contributing to Model Registry using Apple-silicon/ARM-based computers + +Some limitations apply when developing on this project, specifically using Apple-silicon and Mac OSX. +The content from this guide might also be applicable in part for general ARM-based developers/users, beyond Mac OSX. + +## Makefile + +The make command shipped with Mac OSX (at the time of writing) is a bit old: + +``` +% make --version +GNU Make 3.81 +Copyright (C) 2006 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. + +This program built for i386-apple-darwin11.3.0 +``` + + and known to cause problems when using this project's Makefile: + +``` +% make build +openapi-generator-cli validate -i api/openapi/model-registry.yaml +make: openapi-generator-cli: No such file or directory +make: *** [openapi/validate] Error 1 +``` + +i.e. failing to locate the `bin/` executables managed in the Makefile. + +The solution is to use and updated version of `make`. + +You can install it with Homebrew: + +``` +% brew install make +... +==> Pouring make--4.4.1.arm64_ventura.bottle.tar.gz +==> Caveats +GNU "make" has been installed as "gmake". +If you need to use it as "make", you can add a "gnubin" directory +to your PATH from your bashrc like: + + PATH="/opt/homebrew/opt/make/libexec/gnubin:$PATH" +... +``` + +and now you can substitute `gmake` every time the make command is mentioned in guides (or perform the path management per the caveat). + +## Docker engine + +Several options of docker engines are available for Mac. +Having Docker installed is also helpful for Testcontainers. + +### Colima + +Colima offers Rosetta (Apple specific) emulation which is handy since the Google MLMD project dependency is x86 specific. +You can install Colima (and Docker) with Homebrew. + +You can create a Colima "docker context" focusing on x86 emulation with: + +``` +colima start --vz-rosetta --vm-type vz --arch x86_64 --cpu 4 --memory 8 +``` + +To use with *Testcontainers for Go* you can use these commands: + +``` +export DOCKER_HOST="unix://${HOME}/.colima/default/docker.sock" +export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE="/var/run/docker.sock" +``` + +as instructed in [this guide](https://golang.testcontainers.org/system_requirements/using_colima/#:~:text=Set%20the%20DOCKER_HOST%20environment). + +This colima setups allows to: +- launch Integration tests in Go (used in Core go layer) with Testcontainers for Go +- launch DevContainer to be able to install MLMD python wheel dependency (which is x86 specific) + +## DevContainer + +Using a [DevContainer](https://containers.dev) is helpful to develop with the Model Registry Python client, since it needs to wrap MLMD python dependency (which is [x86 specific](https://pypi.org/project/ml-metadata/#files)). + +This allows for instance with [VSCode DevContainer extension](https://code.visualstudio.com/docs/devcontainers/containers) to re-open VSCode window "inside" an x86 emulated docker container. +The experience is very similar to when on GitHub.com you press dot `.` and you get a VSCode "inside something", except it is local to your machine. +It's not super fast because x86 is emulated via Rosetta, but works "good enough" to complete most tasks without requiring remote connection to a real x86 server. + +To use DevContainer as a framework directly, a command-line tool and an SDK is available as well on the upstream project: https://containers.dev. + +Don't forget you will need a Docker context for x86 emulation, for instance with colima (see previous step) this can be achieved with: + +``` +colima start --vz-rosetta --vm-type vz --arch x86_64 --cpu 4 --memory 8 +``` + +Define this `.devcontainer/devcontainer.json` file : +```jsonc +{ + "name": "Python 3", + // "image": "mcr.microsoft.com/devcontainers/python:1-3.10-bullseye" + "build": { + "dockerfile": "Dockerfile" + }, + "runArgs": [ + "--network=host" + ], + "customizations": { + "vscode": { + "extensions": [ + // does not work well in DevContainer: "robocorp.robotframework-lsp", + "d-biehl.robotcode" + ] + } + }, +//... +} +``` + +The `network=host` allow from _inside_ the devcontainer to reach any "service" exposed on your computer (host). +This is helpful if other containers are started on your computer (eg: a PostgreSQL or DB in another container). + +The `customizations.vscode.extensions` pre-loads additional extensions needed in VSCode to be executing from *inside* the DevContainer. + +Define this `.devcontainer/Dockerfile` file: + +```docker +FROM mcr.microsoft.com/devcontainers/python:1-3.10-bullseye + +# Here I use the USER from the FROM image +ARG USERNAME=vscode +ARG GROUPNAME=vscode + +# Here I use the UID/GID from _my_ computer, as I'm _not_ using Docker Desktop +ARG USER_UID=501 +ARG USER_GID=20 + +RUN groupmod --gid $USER_GID -o $GROUPNAME \ + && usermod --uid $USER_UID --gid $USER_GID $USERNAME \ + && chown -R $USER_UID:$USER_GID /home/$USERNAME + +# General setup which is "cached" for convenience +RUN pip install -U pip setuptools +RUN pip install -U poetry +RUN pip install -U "ml-metadata==1.14.0" +RUN pip install -U robotframework +RUN pip install -U robotframework-requests +RUN pip install -U PyYAML +``` + +The group/user is needed as on Mac anything _but_ Docker Desktop will need to set correct FS permissions. (more details here: `https://github.com/devcontainers/spec/issues/325`). + +The RUN pip install "caches" the local installation (inside the DevContainer) of some wheels which are almost always needed, for convenience. + +Please notice the line `RUN pip install -U "ml-metadata==1.14.0"`: that pip install would otherwise fail on Apple-silicon/ARM-based machines. + +E.g. when issued on bare-metal-Apple-silicon fails with: +``` +% pip install -U "ml-metadata==1.14.0" +ERROR: Could not find a version that satisfies the requirement ml-metadata==1.14.0 (from versions: 0.12.0.dev0, 0.13.0.dev0, 0.13.1.dev0) +ERROR: No matching distribution found for ml-metadata==1.14.0 +``` + +As all the wheels are x86 specific: https://pypi.org/project/ml-metadata/1.14.0/#files + +So it's not even possible to receive code assists. However, after clicking to re-open the project inside an (emulated) DevContainer: + +![](doc/Screenshot%202023-11-29%20at%2014.08.12.png) + +Then with the given setup MLMD is already installed inside the DevContainer: + +![](doc/Screenshot%202023-11-29%20at%2014.10.14.png) + +At this point Poetry is already installed as well and can be used to build and run test of the Model Registry Python client. + + \ No newline at end of file diff --git a/doc/Screenshot 2023-11-29 at 14.08.12.png b/doc/Screenshot 2023-11-29 at 14.08.12.png new file mode 100644 index 0000000000000000000000000000000000000000..fbdfc13e4e72a5fbcd6862ebb36e982ae20a07ab GIT binary patch literal 345093 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 n%SSayayGpl1lwko;) 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 Date: Tue, 12 Dec 2023 07:12:22 +0000 Subject: [PATCH 182/254] build(deps): bump actions/setup-python from 4 to 5 (#232) --- .github/workflows/build.yml | 2 +- .github/workflows/python-client.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5ed8087c..a636a8bd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,7 @@ jobs: version: "24.3" repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: 3.9 - name: Install makefile dependencies diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-client.yml index 4ffeb8c1..5dd07670 100644 --- a/.github/workflows/python-client.yml +++ b/.github/workflows/python-client.yml @@ -29,7 +29,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v4.6.1 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} From 3f53d77555b31eb373c4ac297def62301edb89a6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 07:15:07 +0000 Subject: [PATCH 183/254] build(deps): bump github.com/spf13/viper from 1.17.0 to 1.18.1 (#234) --- go.mod | 19 ++- go.sum | 435 +++------------------------------------------------------ 2 files changed, 29 insertions(+), 425 deletions(-) diff --git a/go.mod b/go.mod index 75f635db..6e938995 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/golang/glog v1.2.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.17.0 + github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 google.golang.org/grpc v1.59.0 @@ -19,12 +19,11 @@ require ( github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/sagikazarmark/locafero v0.3.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/sync v0.5.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -40,7 +39,7 @@ require ( github.com/docker/docker v24.0.7+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -64,18 +63,18 @@ require ( github.com/shirou/gopsutil/v3 v3.23.9 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/spf13/afero v1.10.0 // indirect - github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/net v0.19.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect golang.org/x/tools v0.13.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index 23b99352..394d921e 100644 --- a/go.sum +++ b/go.sum @@ -1,64 +1,17 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4= github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= @@ -84,110 +37,40 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -221,19 +104,16 @@ github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6 github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ= -github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= @@ -249,23 +129,21 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= -github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= -github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= -github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= +github.com/spf13/viper v1.18.1 h1:rmuU42rScKWlhhJDyXZRKJQHXFX02chSVW1IvkPGiVM= +github.com/spf13/viper v1.18.1/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= @@ -283,344 +161,81 @@ github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9f github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -628,13 +243,3 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From c694a9e75fb6145d7220cfd79613ae56f57b1367 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 07:16:03 +0000 Subject: [PATCH 184/254] build(deps): bump actions/setup-go from 4 to 5 (#233) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a636a8bd..2fdbcdd3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: '1.19' - name: Install Protoc From 84a03e01c6dcc9f567af2815d1d01919b6b0d7aa Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 5 Dec 2023 17:03:18 -0300 Subject: [PATCH 185/254] GHA: add workflow to publish python client on PyPI This builds and publishes tagged releases of the Python client. Signed-off-by: Isabella Basso do Amaral --- .github/workflows/python-release.yml | 53 +++++++++++++++++++ .../{python-client.yml => python-tests.yml} | 0 2 files changed, 53 insertions(+) create mode 100644 .github/workflows/python-release.yml rename .github/workflows/{python-client.yml => python-tests.yml} (100%) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml new file mode 100644 index 00000000..93bbf50a --- /dev/null +++ b/.github/workflows/python-release.yml @@ -0,0 +1,53 @@ +name: Release Python client + +on: + push: + tags: + - py-v* + workflow_dispatch: + +jobs: + release: + name: Release + runs-on: ubuntu-latest + permissions: + id-token: write + + env: + FORCE_COLOR: "1" + + steps: + - name: Check out the repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.10" + + - name: Upgrade pip + run: | + pip install --constraint=.github/workflows/constraints.txt pip + pip --version + + - name: Install Poetry + run: | + pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry + poetry --version + + - name: Check version + run: | + set -o pipefail + [[ $(poetry version | cut -d' ' -f1) == $(grep -o '[0-9\.]*' <<< "$GITHUB_REF") ]] ||\ + echo "::error title='$GITHUB_REF tag does not match project version'::" + + - name: Build package + working-directory: clients/python + run: | + poetry build --ansi + + - name: Publish package on PyPI + if: github.event_name == 'release' + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: clients/python/dist/ diff --git a/.github/workflows/python-client.yml b/.github/workflows/python-tests.yml similarity index 100% rename from .github/workflows/python-client.yml rename to .github/workflows/python-tests.yml From f752ce4020f24f4fcca7a6cf43d98d46253f8e77 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 12 Dec 2023 18:47:19 -0300 Subject: [PATCH 186/254] GHA: fix py release version check cwd Signed-off-by: Isabella Basso do Amaral --- .github/workflows/python-release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 93bbf50a..a349f7e3 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -36,6 +36,7 @@ jobs: poetry --version - name: Check version + working-directory: clients/python run: | set -o pipefail [[ $(poetry version | cut -d' ' -f1) == $(grep -o '[0-9\.]*' <<< "$GITHUB_REF") ]] ||\ From f720231079aed9db3a57814975fe18c7efa62486 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 12 Dec 2023 18:47:19 -0300 Subject: [PATCH 187/254] GHA: fix pypi publish activation rules Signed-off-by: Isabella Basso do Amaral --- .github/workflows/python-release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index a349f7e3..42e79a60 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -48,7 +48,8 @@ jobs: poetry build --ansi - name: Publish package on PyPI - if: github.event_name == 'release' uses: pypa/gh-action-pypi-publish@release/v1 with: + verbose: true + print-hash: true packages-dir: clients/python/dist/ From b07bacef8608a44328750ad886c9689061de1f12 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 12 Dec 2023 18:47:19 -0300 Subject: [PATCH 188/254] GHA: fix py release on manual dispatch Signed-off-by: Isabella Basso do Amaral --- .github/workflows/python-release.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 42e79a60..489cd024 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -39,8 +39,11 @@ jobs: working-directory: clients/python run: | set -o pipefail - [[ $(poetry version | cut -d' ' -f1) == $(grep -o '[0-9\.]*' <<< "$GITHUB_REF") ]] ||\ - echo "::error title='$GITHUB_REF tag does not match project version'::" + LATEST_TAG=$(git describe --tags --match="py-v*") + if [[ "$LATEST_TAG" =~ $(poetry version | cut -d' ' -f1) ]]; then + echo "::error title='$LATEST_TAG tag does not match project version'::" + exit 1 + fi - name: Build package working-directory: clients/python From df45e908046badbe196d75ce9fa03dc582e22440 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 12 Dec 2023 20:45:55 -0300 Subject: [PATCH 189/254] Fix typo: move opeanpi -> openapi Signed-off-by: Isabella Basso do Amaral --- .../{opeanpi_converter.go => openapi_converter.go} | 0 internal/converter/openapi_converter_test.go | 10 ++++++---- 2 files changed, 6 insertions(+), 4 deletions(-) rename internal/converter/{opeanpi_converter.go => openapi_converter.go} (100%) diff --git a/internal/converter/opeanpi_converter.go b/internal/converter/openapi_converter.go similarity index 100% rename from internal/converter/opeanpi_converter.go rename to internal/converter/openapi_converter.go diff --git a/internal/converter/openapi_converter_test.go b/internal/converter/openapi_converter_test.go index 36f256f9..a2f1d431 100644 --- a/internal/converter/openapi_converter_test.go +++ b/internal/converter/openapi_converter_test.go @@ -134,9 +134,11 @@ func checkEntity(entity *oapiEntity) []string { // test -var converterMethodPattern *regexp.Regexp = regexp.MustCompile(`Convert(?P\w+)Update`) -var overrideNotEditableMethodPattern *regexp.Regexp = regexp.MustCompile(`OverrideNotEditableFor(?P\w+)`) -var ignoreDirectivePattern *regexp.Regexp = regexp.MustCompile(`// goverter:ignore (?P.+)`) +var ( + converterMethodPattern *regexp.Regexp = regexp.MustCompile(`Convert(?P\w+)Update`) + overrideNotEditableMethodPattern *regexp.Regexp = regexp.MustCompile(`OverrideNotEditableFor(?P\w+)`) + ignoreDirectivePattern *regexp.Regexp = regexp.MustCompile(`// goverter:ignore (?P.+)`) +) func TestOverrideNotEditableFields(t *testing.T) { _ = setup(t) @@ -146,7 +148,7 @@ func TestOverrideNotEditableFields(t *testing.T) { if err != nil { t.Errorf("error getting current working directory") } - filePath := fmt.Sprintf("%s/opeanpi_converter.go", wd) + filePath := fmt.Sprintf("%s/openapi_converter.go", wd) f, _ := parser.ParseFile(fset, filePath, nil, parser.ParseComments) v := newVisitor(t, f) From c2664e54b926c15fb024730b264ec2c86020f064 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Tue, 12 Dec 2023 20:07:58 -0300 Subject: [PATCH 190/254] robot: fix Py client import Signed-off-by: Isabella Basso do Amaral --- test/robot/MLMetadata.py | 13 ++++++------- test/robot/ModelRegistry.py | 15 ++++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/test/robot/MLMetadata.py b/test/robot/MLMetadata.py index 5021fdef..eed40672 100644 --- a/test/robot/MLMetadata.py +++ b/test/robot/MLMetadata.py @@ -1,19 +1,18 @@ +from ml_metadata import proto from ml_metadata.metadata_store import metadata_store -from ml_metadata.metadata_store.metadata_store import ListOptions from ml_metadata.proto import metadata_store_pb2 -from ml_metadata import proto -from typing import List, Optional + class MLMetadata(metadata_store.MetadataStore): - def __init__(self, host: str = 'localhost', port: int = 9090): + def __init__(self, host: str = "localhost", port: int = 9090): client_connection_config = metadata_store_pb2.MetadataStoreClientConfig() client_connection_config.host = host client_connection_config.port = port print(client_connection_config) super().__init__(client_connection_config) - def get_context_by_single_id(self, context_id: int) -> List[proto.Context]: + def get_context_by_single_id(self, context_id: int) -> list[proto.Context]: return self.get_contexts_by_id([context_id])[0] - def get_artifact_by_single_id(self, artifact_id: int) -> List[proto.Artifact]: - return self.get_artifacts_by_id([artifact_id])[0] \ No newline at end of file + def get_artifact_by_single_id(self, artifact_id: int) -> list[proto.Artifact]: + return self.get_artifacts_by_id([artifact_id])[0] diff --git a/test/robot/ModelRegistry.py b/test/robot/ModelRegistry.py index 6036ae48..b514cd9b 100644 --- a/test/robot/ModelRegistry.py +++ b/test/robot/ModelRegistry.py @@ -2,13 +2,14 @@ from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel from robot.libraries.BuiltIn import BuiltIn + def write_to_console(s): print(s) BuiltIn().log_to_console(s) -class ModelRegistry(mr.client.ModelRegistry): - def __init__(self, host: str = 'localhost', port: int = 9090): +class ModelRegistry(mr.core.ModelRegistryAPIClient): + def __init__(self, host: str = "localhost", port: int = 9090): super().__init__(host, port) def upsert_registered_model(self, registered_model) -> str: @@ -16,7 +17,7 @@ def upsert_registered_model(self, registered_model) -> str: for key, value in registered_model.items(): setattr(p, key, value) return super().upsert_registered_model(p) - + def upsert_model_version(self, model_version, registered_model_id: str) -> str: write_to_console(model_version) p = ModelVersion(ModelArtifact("", ""), "", "") @@ -24,7 +25,7 @@ def upsert_model_version(self, model_version, registered_model_id: str) -> str: setattr(p, key, value) write_to_console(p) return super().upsert_model_version(p, registered_model_id) - + def upsert_model_artifact(self, model_artifact, model_version_id: str) -> str: write_to_console(model_artifact) p = ModelArtifact(None, None) @@ -34,8 +35,8 @@ def upsert_model_artifact(self, model_artifact, model_version_id: str) -> str: return super().upsert_model_artifact(p, model_version_id) -# Used only for quick smoke tests +# Used only for quick smoke tests if __name__ == "__main__": demo_instance = ModelRegistry() - demo_instance.upsert_registered_model({'name': 'testing123'}) - demo_instance.upsert_model_version({'name': 'v1'}, None) + demo_instance.upsert_registered_model({"name": "testing123"}) + demo_instance.upsert_model_version({"name": "v1"}, None) From 077be7c351c6a778a73db705422526e820a7949b Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 13 Dec 2023 11:05:06 -0300 Subject: [PATCH 191/254] robot: fix Py client obj creation Signed-off-by: Isabella Basso do Amaral --- test/robot/ModelRegistry.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/robot/ModelRegistry.py b/test/robot/ModelRegistry.py index b514cd9b..4b5d1090 100644 --- a/test/robot/ModelRegistry.py +++ b/test/robot/ModelRegistry.py @@ -13,14 +13,14 @@ def __init__(self, host: str = "localhost", port: int = 9090): super().__init__(host, port) def upsert_registered_model(self, registered_model) -> str: - p = RegisteredModel(None) + p = RegisteredModel("") for key, value in registered_model.items(): setattr(p, key, value) return super().upsert_registered_model(p) def upsert_model_version(self, model_version, registered_model_id: str) -> str: write_to_console(model_version) - p = ModelVersion(ModelArtifact("", ""), "", "") + p = ModelVersion("", "", "") for key, value in model_version.items(): setattr(p, key, value) write_to_console(p) @@ -28,7 +28,7 @@ def upsert_model_version(self, model_version, registered_model_id: str) -> str: def upsert_model_artifact(self, model_artifact, model_version_id: str) -> str: write_to_console(model_artifact) - p = ModelArtifact(None, None) + p = ModelArtifact("", "") for key, value in model_artifact.items(): setattr(p, key, value) write_to_console(p) From 7b351c23bdd266056ff05a7bb6c42d26788c58c9 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 13 Dec 2023 11:10:24 -0300 Subject: [PATCH 192/254] GHA: fetch tags on py release checkout action Signed-off-by: Isabella Basso do Amaral --- .github/workflows/python-release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index 489cd024..dc529ced 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -19,6 +19,8 @@ jobs: steps: - name: Check out the repository uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 From e56fc362014f695079e8ecd42ddd7c1305f4f57b Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Fri, 15 Dec 2023 10:05:00 +0100 Subject: [PATCH 193/254] py: using Testcontainers and test strategy as go (#225) * py: using Testcontainers and test strategy as go * align nox file Co-authored-by: Andrea Lamparelli * Update clients/python/tests/conftest.py Co-authored-by: Isabella Basso * make use of posix path properly in conftest * linting * Update clients/python/tests/conftest.py Co-authored-by: Isabella Basso * Update clients/python/tests/conftest.py Co-authored-by: Isabella Basso * Update clients/python/tests/conftest.py * Update clients/python/tests/conftest.py Co-authored-by: Isabella Basso * Update clients/python/tests/conftest.py Co-authored-by: Isabella Basso * Update clients/python/tests/conftest.py Co-authored-by: Isabella Basso * apply manual correction * apply strategy change for file delete * remove fixture autouse --------- Co-authored-by: Andrea Lamparelli Co-authored-by: Isabella Basso --- clients/python/noxfile.py | 2 +- clients/python/poetry.lock | 228 ++++++++++++++++++++++++++++--- clients/python/pyproject.toml | 5 + clients/python/tests/conftest.py | 86 +++++++++++- 4 files changed, 294 insertions(+), 27 deletions(-) diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py index 2e9bb70d..7e35e75f 100644 --- a/clients/python/noxfile.py +++ b/clients/python/noxfile.py @@ -49,7 +49,7 @@ def mypy(session: Session) -> None: def tests(session: Session) -> None: """Run the test suite.""" session.install(".") - session.install("coverage[toml]", "pytest", "pytest-cov", "pygments") + session.install("coverage[toml]", "pytest", "pytest-cov", "pygments", "testcontainers") try: session.run( "pytest", diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock index 3e4e1632..6564f886 100644 --- a/clients/python/poetry.lock +++ b/clients/python/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.7.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "absl-py" @@ -259,6 +259,41 @@ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.1 [package.extras] toml = ["tomli"] +[[package]] +name = "deprecation" +version = "2.1.0" +description = "A library to handle automated deprecations" +optional = false +python-versions = "*" +files = [ + {file = "deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a"}, + {file = "deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff"}, +] + +[package.dependencies] +packaging = "*" + +[[package]] +name = "docker" +version = "6.1.3" +description = "A Python library for the Docker Engine API." +optional = false +python-versions = ">=3.7" +files = [ + {file = "docker-6.1.3-py3-none-any.whl", hash = "sha256:aecd2277b8bf8e506e484f6ab7aec39abe0038e29fa4a6d3ba86c3fe01844ed9"}, + {file = "docker-6.1.3.tar.gz", hash = "sha256:aa6d17830045ba5ef0168d5eaa34d37beeb113948c413affe1d5991fc11f9a20"}, +] + +[package.dependencies] +packaging = ">=14.0" +pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} +requests = ">=2.26.0" +urllib3 = ">=1.26.0" +websocket-client = ">=0.32.0" + +[package.extras] +ssh = ["paramiko (>=2.4.3)"] + [[package]] name = "docutils" version = "0.20.1" @@ -369,13 +404,13 @@ protobuf = ["grpcio-tools (>=1.59.3)"] [[package]] name = "idna" -version = "3.4" +version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.5" files = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] [[package]] @@ -391,20 +426,20 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.8.0" +version = "7.0.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, - {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, + {file = "importlib_metadata-7.0.0-py3-none-any.whl", hash = "sha256:d97503976bb81f40a193d41ee6570868479c69d5068651eb039c40d850c59d67"}, + {file = "importlib_metadata-7.0.0.tar.gz", hash = "sha256:7fc841f8b8332803464e5dc1c63a2e59121f46ca186c0e2e182e80bf8c1319f7"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] @@ -816,6 +851,29 @@ pytest = ">=4.6" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + [[package]] name = "pyyaml" version = "6.0.1" @@ -1130,6 +1188,39 @@ Sphinx = ">=5" lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "testcontainers" +version = "3.7.1" +description = "Library provides lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container" +optional = false +python-versions = ">=3.7" +files = [ + {file = "testcontainers-3.7.1-py2.py3-none-any.whl", hash = "sha256:7f48cef4bf0ccd78f1a4534d4b701a003a3bace851f24eae58a32f9e3f0aeba0"}, +] + +[package.dependencies] +deprecation = "*" +docker = ">=4.0.0" +wrapt = "*" + +[package.extras] +arangodb = ["python-arango"] +azurite = ["azure-storage-blob"] +clickhouse = ["clickhouse-driver"] +docker-compose = ["docker-compose"] +google-cloud-pubsub = ["google-cloud-pubsub (<2)"] +kafka = ["kafka-python"] +keycloak = ["python-keycloak"] +mongo = ["pymongo"] +mssqlserver = ["pymssql"] +mysql = ["pymysql", "sqlalchemy"] +neo4j = ["neo4j"] +oracle = ["cx-Oracle", "sqlalchemy"] +postgresql = ["psycopg2-binary", "sqlalchemy"] +rabbitmq = ["pika"] +redis = ["redis"] +selenium = ["selenium"] + [[package]] name = "tomli" version = "2.0.1" @@ -1143,22 +1234,22 @@ files = [ [[package]] name = "tornado" -version = "6.3.3" +version = "6.4" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." optional = false python-versions = ">= 3.8" files = [ - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d"}, - {file = "tornado-6.3.3-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a"}, - {file = "tornado-6.3.3-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16"}, - {file = "tornado-6.3.3-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17"}, - {file = "tornado-6.3.3-cp38-abi3-win32.whl", hash = "sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3"}, - {file = "tornado-6.3.3-cp38-abi3-win_amd64.whl", hash = "sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5"}, - {file = "tornado-6.3.3.tar.gz", hash = "sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, + {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, + {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, + {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, ] [[package]] @@ -1202,6 +1293,101 @@ brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "websocket-client" +version = "1.7.0" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket-client-1.7.0.tar.gz", hash = "sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6"}, + {file = "websocket_client-1.7.0-py3-none-any.whl", hash = "sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + +[[package]] +name = "wrapt" +version = "1.16.0" +description = "Module for decorators, wrappers and monkey patching." +optional = false +python-versions = ">=3.6" +files = [ + {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, + {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, + {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, + {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, + {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, + {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, + {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, + {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, + {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, + {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, + {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, + {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, + {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, + {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, + {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, + {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, + {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, + {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, + {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, + {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, + {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, + {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, + {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, + {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, + {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, + {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, + {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, + {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, + {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, + {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, + {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, + {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, + {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, + {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, + {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, + {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, + {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, +] + [[package]] name = "zipp" version = "3.17.0" @@ -1220,4 +1406,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 3.11" -content-hash = "323e9f5ac3a2a98f69554c3e2d36f75112b75517faa70637fb94256f8052c5fc" +content-hash = "0bec6ced2c16af94b1fc60510507065880d70bf1f3e786da393233ee345ed15c" diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 757b863d..3e9bcfc7 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -10,6 +10,10 @@ readme = "README.md" python = ">= 3.9, < 3.11" attrs = "^21.0" ml-metadata = "^1.14.0" +# Testcontainers for python, remote mlmd grpc tested with: +# ml-metadata = { url = "https://github.com/tarilabs/ml-metadata/releases/download/1.14.0/ml_metadata-1.14.0-py3-none-any.whl" } +# or might consider as well: +# ml-metadata = { url = "https://github.com/tarilabs/ml-metadata-remote/releases/download/1.14.0/ml_metadata-1.14.0-py3-none-any.whl" } typing-extensions = "^4.8" [tool.poetry.group.dev.dependencies] @@ -22,6 +26,7 @@ pytest-cov = "^4.1.0" sphinx-autobuild = "^2021.3.14" ruff = "^0.1.6" mypy = "^1.7.0" +testcontainers = "^3.7.1" [tool.coverage.run] branch = true diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py index d45d65ba..faf3df4b 100644 --- a/clients/python/tests/conftest.py +++ b/clients/python/tests/conftest.py @@ -1,24 +1,81 @@ +import os +import time from typing import Union import pytest +from ml_metadata import errors, metadata_store from ml_metadata.proto import ( ArtifactType, - ConnectionConfig, ContextType, metadata_store_pb2, ) +from ml_metadata.proto.metadata_store_pb2 import MetadataStoreClientConfig from model_registry.core import ModelRegistryAPIClient from model_registry.store.wrapper import MLMDStore from model_registry.types import ModelArtifact, ModelVersion, RegisteredModel +from testcontainers.core.container import DockerContainer +from testcontainers.core.waiting_utils import wait_for_logs ProtoTypeType = Union[ArtifactType, ContextType] +# ruff: noqa: PT021 supported +@pytest.fixture(scope="session") +def mlmd_conn(request) -> MetadataStoreClientConfig: + model_registry_root_dir = model_registry_root(request) + print("Assuming this is the Model Registry root directory:", model_registry_root_dir) + shared_volume = model_registry_root_dir / "test/config/ml-metadata" + sqlite_db_file = shared_volume / "metadata.sqlite.db" + if sqlite_db_file.exists(): + msg = f"The file {sqlite_db_file} already exists; make sure to cancel it before running these tests." + raise FileExistsError(msg) + container = DockerContainer("gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0") + container.with_exposed_ports(8080) + container.with_volume_mapping(shared_volume, "/tmp/shared", "rw") # noqa this is file target in container + container.with_env("METADATA_STORE_SERVER_CONFIG_FILE", "/tmp/shared/conn_config.pb") # noqa this is target in container + container.start() + wait_for_logs(container, "Server listening on") + os.system('docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a') # noqa governed test + print("waited for logs and port") + cfg = MetadataStoreClientConfig( + host = "localhost", + port = int(container.get_exposed_port(8080)) + ) + print(cfg) + + # this callback is needed in order to perform the container.stop() + # removing this callback might result in mlmd container shutting down before the tests had chance to fully run, + # and resulting in grpc connection resets. + def teardown(): + container.stop() + print("teardown of plain_wrapper completed.") + + request.addfinalizer(teardown) + + time.sleep(3) # allowing some time for mlmd grpc to fully stabilize (is "spent" once per pytest session anyway) + _throwaway_store = metadata_store.MetadataStore(cfg) + wait_for_grpc(container, _throwaway_store) + + return cfg + + +def model_registry_root(request): + return (request.config.rootpath / "../..").resolve() # resolves to absolute path + @pytest.fixture() -def plain_wrapper() -> MLMDStore: - config = ConnectionConfig() - config.fake_database.SetInParent() - return MLMDStore(config) +def plain_wrapper(request, mlmd_conn: MetadataStoreClientConfig) -> MLMDStore: + sqlite_db_file = model_registry_root(request) / "test/config/ml-metadata/metadata.sqlite.db" + def teardown(): + try: + os.remove(sqlite_db_file) + print(f"Removed {sqlite_db_file} successfully.") + except Exception as e: + print(f"An error occurred while removing {sqlite_db_file}: {e}") + print("plain_wrapper_after_each done.") + + request.addfinalizer(teardown) + + return MLMDStore(mlmd_conn) def set_type_attrs(mlmd_obj: ProtoTypeType, name: str, props: list[str]): @@ -78,3 +135,22 @@ def mr_api(store_wrapper: MLMDStore) -> ModelRegistryAPIClient: mr = object.__new__(ModelRegistryAPIClient) mr._store = store_wrapper return mr + + +def wait_for_grpc(container: DockerContainer, store: metadata_store.MetadataStore, timeout=6, interval=2): + start = time.time() + while True: + duration = time.time() - start + results = None + try: + results = store.get_contexts() + except errors.UnavailableError as e: + print(e) + print("Container logs:\n", container.get_logs()) + print("Container not ready. Retrying...") + if results is not None: + return duration + if timeout and duration > timeout: + raise TimeoutError("wait_for_grpc not ready %.3f seconds" + % timeout) + time.sleep(interval) From 51b45f156e84f2548c3ee65d567ccf234b64cb6c Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 15 Dec 2023 16:36:18 +0100 Subject: [PATCH 194/254] Change state to desiredState for InferenceService (#243) --- api/openapi/model-registry.yaml | 2 +- .../generated/mlmd_openapi_converter.gen.go | 6 +-- .../generated/openapi_converter.gen.go | 12 ++--- .../converter/mlmd_converter_util_test.go | 26 ++++++----- internal/converter/mlmd_openapi_converter.go | 6 +-- .../converter/mlmd_openapi_converter_util.go | 24 +++------- internal/converter/openapi_converter.go | 2 +- .../converter/openapi_mlmd_converter_util.go | 6 +-- pkg/core/core.go | 2 +- pkg/core/core_test.go | 10 ++--- pkg/openapi/model_inference_service.go | 44 +++++++++---------- pkg/openapi/model_inference_service_create.go | 44 +++++++++---------- pkg/openapi/model_inference_service_update.go | 44 +++++++++---------- 13 files changed, 109 insertions(+), 119 deletions(-) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index dc3698fd..ff2940a0 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -1576,7 +1576,7 @@ components: runtime: description: Model runtime. type: string - state: + desiredState: $ref: '#/components/schemas/InferenceServiceState' InferenceServiceCreate: description: >- diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index d6e5c4cf..0be2c2a5 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -33,7 +33,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertInferenceService(source *proto.Conte openapiInferenceService.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) openapiInferenceService.ModelVersionId = converter.MapPropertyModelVersionId((*source).Properties) openapiInferenceService.Runtime = converter.MapPropertyRuntime((*source).Properties) - openapiInferenceService.State = converter.MapInferenceServiceState(source) + openapiInferenceService.DesiredState = converter.MapInferenceServiceDesiredState((*source).Properties) openapiInferenceService.RegisteredModelId = converter.MapPropertyRegisteredModelId((*source).Properties) openapiInferenceService.ServingEnvironmentId = converter.MapPropertyServingEnvironmentId((*source).Properties) pOpenapiInferenceService = &openapiInferenceService @@ -98,7 +98,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertModelVersion(source *proto.Context) } openapiModelVersion.ExternalID = pString openapiModelVersion.Name = converter.MapNameFromOwned((*source).Name) - openapiModelVersion.State = converter.MapModelVersionState(source) + openapiModelVersion.State = converter.MapModelVersionState((*source).Properties) openapiModelVersion.Author = converter.MapPropertyAuthor((*source).Properties) openapiModelVersion.Id = converter.Int64ToString((*source).Id) openapiModelVersion.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) @@ -132,7 +132,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertRegisteredModel(source *proto.Contex openapiRegisteredModel.Id = converter.Int64ToString((*source).Id) openapiRegisteredModel.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) openapiRegisteredModel.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) - openapiRegisteredModel.State = converter.MapRegisteredModelState(source) + openapiRegisteredModel.State = converter.MapRegisteredModelState((*source).Properties) pOpenapiRegisteredModel = &openapiRegisteredModel } return pOpenapiRegisteredModel, nil diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index 17f14917..2603742b 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -53,11 +53,11 @@ func (c *OpenAPIConverterImpl) ConvertInferenceServiceCreate(source *openapi.Inf } openapiInferenceService.Runtime = pString5 var pOpenapiInferenceServiceState *openapi.InferenceServiceState - if (*source).State != nil { - openapiInferenceServiceState := openapi.InferenceServiceState(*(*source).State) + if (*source).DesiredState != nil { + openapiInferenceServiceState := openapi.InferenceServiceState(*(*source).DesiredState) pOpenapiInferenceServiceState = &openapiInferenceServiceState } - openapiInferenceService.State = pOpenapiInferenceServiceState + openapiInferenceService.DesiredState = pOpenapiInferenceServiceState openapiInferenceService.RegisteredModelId = (*source).RegisteredModelId openapiInferenceService.ServingEnvironmentId = (*source).ServingEnvironmentId pOpenapiInferenceService = &openapiInferenceService @@ -102,11 +102,11 @@ func (c *OpenAPIConverterImpl) ConvertInferenceServiceUpdate(source *openapi.Inf } openapiInferenceService.Runtime = pString4 var pOpenapiInferenceServiceState *openapi.InferenceServiceState - if (*source).State != nil { - openapiInferenceServiceState := openapi.InferenceServiceState(*(*source).State) + if (*source).DesiredState != nil { + openapiInferenceServiceState := openapi.InferenceServiceState(*(*source).DesiredState) pOpenapiInferenceServiceState = &openapiInferenceServiceState } - openapiInferenceService.State = pOpenapiInferenceServiceState + openapiInferenceService.DesiredState = pOpenapiInferenceServiceState pOpenapiInferenceService = &openapiInferenceService } return pOpenapiInferenceService, nil diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index 1251da3f..d2f063c0 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -544,13 +544,13 @@ func TestMapMLMDModelArtifactState(t *testing.T) { func TestMapRegisteredModelState(t *testing.T) { assertion := setup(t) - state := MapRegisteredModelState(&proto.Context{Properties: map[string]*proto.Value{ + state := MapRegisteredModelState(map[string]*proto.Value{ "state": {Value: &proto.Value_StringValue{StringValue: string(openapi.REGISTEREDMODELSTATE_LIVE)}}, - }}) + }) assertion.NotNil(state) assertion.Equal(openapi.REGISTEREDMODELSTATE_LIVE, *state) - state = MapRegisteredModelState(&proto.Context{Properties: map[string]*proto.Value{}}) + state = MapRegisteredModelState(map[string]*proto.Value{}) assertion.Nil(state) state = MapRegisteredModelState(nil) @@ -560,13 +560,13 @@ func TestMapRegisteredModelState(t *testing.T) { func TestMapModelVersionState(t *testing.T) { assertion := setup(t) - state := MapModelVersionState(&proto.Context{Properties: map[string]*proto.Value{ + state := MapModelVersionState(map[string]*proto.Value{ "state": {Value: &proto.Value_StringValue{StringValue: string(openapi.MODELVERSIONSTATE_LIVE)}}, - }}) + }) assertion.NotNil(state) assertion.Equal(openapi.MODELVERSIONSTATE_LIVE, *state) - state = MapModelVersionState(&proto.Context{Properties: map[string]*proto.Value{}}) + state = MapModelVersionState(map[string]*proto.Value{}) assertion.Nil(state) state = MapModelVersionState(nil) @@ -576,16 +576,16 @@ func TestMapModelVersionState(t *testing.T) { func TestMapInferenceServiceState(t *testing.T) { assertion := setup(t) - state := MapInferenceServiceState(&proto.Context{Properties: map[string]*proto.Value{ - "state": {Value: &proto.Value_StringValue{StringValue: string(openapi.INFERENCESERVICESTATE_DEPLOYED)}}, - }}) + state := MapInferenceServiceDesiredState(map[string]*proto.Value{ + "desired_state": {Value: &proto.Value_StringValue{StringValue: string(openapi.INFERENCESERVICESTATE_DEPLOYED)}}, + }) assertion.NotNil(state) assertion.Equal(openapi.INFERENCESERVICESTATE_DEPLOYED, *state) - state = MapInferenceServiceState(&proto.Context{Properties: map[string]*proto.Value{}}) + state = MapInferenceServiceDesiredState(map[string]*proto.Value{}) assertion.Nil(state) - state = MapInferenceServiceState(nil) + state = MapInferenceServiceDesiredState(nil) assertion.Nil(state) } @@ -614,14 +614,16 @@ func TestMapInferenceServiceProperties(t *testing.T) { Runtime: of("my-runtime"), RegisteredModelId: "2", ServingEnvironmentId: "3", + DesiredState: openapi.INFERENCESERVICESTATE_DEPLOYED.Ptr(), }) assertion.Nil(err) - assertion.Equal(5, len(props)) + assertion.Equal(6, len(props)) assertion.Equal("my custom description", props["description"].GetStringValue()) assertion.Equal(int64(1), props["model_version_id"].GetIntValue()) assertion.Equal("my-runtime", props["runtime"].GetStringValue()) assertion.Equal(int64(2), props["registered_model_id"].GetIntValue()) assertion.Equal(int64(3), props["serving_environment_id"].GetIntValue()) + assertion.Equal("DEPLOYED", props["desired_state"].GetStringValue()) // serving and model id must be provided and must be a valid numeric id _, err = MapInferenceServiceProperties(&openapi.InferenceService{}) diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index a9370186..dc28490a 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -15,12 +15,12 @@ import ( // goverter:extend MapMLMDCustomProperties type MLMDToOpenAPIConverter interface { // goverter:map Properties Description | MapDescription - // goverter:map . State | MapRegisteredModelState + // goverter:map Properties State | MapRegisteredModelState ConvertRegisteredModel(source *proto.Context) (*openapi.RegisteredModel, error) // goverter:map Name | MapNameFromOwned // goverter:map Properties Description | MapDescription - // goverter:map . State | MapModelVersionState + // goverter:map Properties State | MapModelVersionState // goverter:map Properties Author | MapPropertyAuthor ConvertModelVersion(source *proto.Context) (*openapi.ModelVersion, error) @@ -45,7 +45,7 @@ type MLMDToOpenAPIConverter interface { // goverter:map Properties ModelVersionId | MapPropertyModelVersionId // goverter:map Properties RegisteredModelId | MapPropertyRegisteredModelId // goverter:map Properties ServingEnvironmentId | MapPropertyServingEnvironmentId - // goverter:map . State | MapInferenceServiceState + // goverter:map Properties DesiredState | MapInferenceServiceDesiredState ConvertInferenceService(source *proto.Context) (*openapi.InferenceService, error) // goverter:map Name | MapNameFromOwned diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 6e0539d7..71f0a0b4 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -89,12 +89,8 @@ func MapArtifactType(source *proto.Artifact) (string, error) { return "", fmt.Errorf("invalid artifact type found: %v", source.Type) } -func MapRegisteredModelState(source *proto.Context) *openapi.RegisteredModelState { - if source == nil || source.GetProperties() == nil { - return nil - } - - state, ok := source.GetProperties()["state"] +func MapRegisteredModelState(properties map[string]*proto.Value) *openapi.RegisteredModelState { + state, ok := properties["state"] if !ok { return nil } @@ -102,12 +98,8 @@ func MapRegisteredModelState(source *proto.Context) *openapi.RegisteredModelStat return (*openapi.RegisteredModelState)(&str) } -func MapModelVersionState(source *proto.Context) *openapi.ModelVersionState { - if source == nil || source.GetProperties() == nil { - return nil - } - - state, ok := source.GetProperties()["state"] +func MapModelVersionState(properties map[string]*proto.Value) *openapi.ModelVersionState { + state, ok := properties["state"] if !ok { return nil } @@ -115,12 +107,8 @@ func MapModelVersionState(source *proto.Context) *openapi.ModelVersionState { return (*openapi.ModelVersionState)(&str) } -func MapInferenceServiceState(source *proto.Context) *openapi.InferenceServiceState { - if source == nil || source.GetProperties() == nil { - return nil - } - - state, ok := source.GetProperties()["state"] +func MapInferenceServiceDesiredState(properties map[string]*proto.Value) *openapi.InferenceServiceState { + state, ok := properties["desired_state"] if !ok { return nil } diff --git a/internal/converter/openapi_converter.go b/internal/converter/openapi_converter.go index 9e6b2e0f..5d504c6c 100644 --- a/internal/converter/openapi_converter.go +++ b/internal/converter/openapi_converter.go @@ -76,7 +76,7 @@ type OpenAPIConverter interface { // Ignore all fields that ARE editable // goverter:default InitInferenceServiceWithUpdate // goverter:autoMap Existing - // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties ModelVersionId Runtime State + // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties ModelVersionId Runtime DesiredState OverrideNotEditableForInferenceService(source OpenapiUpdateWrapper[openapi.InferenceService]) (openapi.InferenceService, error) // Ignore all fields that ARE editable diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index 97fb3c8c..78bbb504 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -336,10 +336,10 @@ func MapInferenceServiceProperties(source *openapi.InferenceService) (map[string } } - if source.State != nil { - props["state"] = &proto.Value{ + if source.DesiredState != nil { + props["desired_state"] = &proto.Value{ Value: &proto.Value_StringValue{ - StringValue: string(*source.State), + StringValue: string(*source.DesiredState), }, } } diff --git a/pkg/core/core.go b/pkg/core/core.go index 9dc9d084..cf53d851 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -107,7 +107,7 @@ func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, // same information tracked using ParentContext association "serving_environment_id": proto.PropertyType_INT, "runtime": proto.PropertyType_STRING, - "state": proto.PropertyType_STRING, + "desired_state": proto.PropertyType_STRING, }, }, } diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index c5eeae7b..3ce08194 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -2125,7 +2125,7 @@ func (suite *CoreTestSuite) TestCreateInferenceService() { parentResourceId := suite.registerServingEnvironment(service, nil, nil) registeredModelId := suite.registerModel(service, nil, nil) runtime := "model-server" - state := openapi.INFERENCESERVICESTATE_DEPLOYED + desiredState := openapi.INFERENCESERVICESTATE_DEPLOYED eut := &openapi.InferenceService{ Name: &entityName, @@ -2134,7 +2134,7 @@ func (suite *CoreTestSuite) TestCreateInferenceService() { ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, Runtime: &runtime, - State: &state, + DesiredState: &desiredState, CustomProperties: &map[string]openapi.MetadataValue{ "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -2165,7 +2165,7 @@ func (suite *CoreTestSuite) TestCreateInferenceService() { suite.Equal(customString, byId.Contexts[0].CustomProperties["custom_string_prop"].GetStringValue(), "saved custom_string_prop custom property should match the provided one") suite.Equal(entityDescription, byId.Contexts[0].Properties["description"].GetStringValue(), "saved description should match the provided one") suite.Equal(runtime, byId.Contexts[0].Properties["runtime"].GetStringValue(), "saved runtime should match the provided one") - suite.Equal(string(state), byId.Contexts[0].Properties["state"].GetStringValue(), "saved state should match the provided one") + suite.Equal(string(desiredState), byId.Contexts[0].Properties["desired_state"].GetStringValue(), "saved state should match the provided one") suite.Equalf(*inferenceServiceTypeName, *byId.Contexts[0].Type, "saved context should be of type of %s", *inferenceServiceTypeName) getAllResp, err := suite.mlmdClient.GetContexts(context.Background(), &proto.GetContextsRequest{}) @@ -2359,7 +2359,7 @@ func (suite *CoreTestSuite) TestGetInferenceServiceById() { Description: &entityDescription, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, - State: &state, + DesiredState: &state, CustomProperties: &map[string]openapi.MetadataValue{ "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -2389,7 +2389,7 @@ func (suite *CoreTestSuite) TestGetInferenceServiceById() { suite.Equal(*getById.Id, *converter.Int64ToString(ctx.Id), "returned id should match the mlmd context one") suite.Equal(*eut.Name, *getById.Name, "saved name should match the provided one") suite.Equal(*eut.ExternalID, *getById.ExternalID, "saved external id should match the provided one") - suite.Equal(*eut.State, *getById.State, "saved state should match the provided one") + suite.Equal(*eut.DesiredState, *getById.DesiredState, "saved state should match the provided one") suite.Equal(*(*getById.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, customString, "saved custom_string_prop custom property should match the provided one") } diff --git a/pkg/openapi/model_inference_service.go b/pkg/openapi/model_inference_service.go index c20699c3..fdd1e4ea 100644 --- a/pkg/openapi/model_inference_service.go +++ b/pkg/openapi/model_inference_service.go @@ -36,8 +36,8 @@ type InferenceService struct { // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` // Model runtime. - Runtime *string `json:"runtime,omitempty"` - State *InferenceServiceState `json:"state,omitempty"` + Runtime *string `json:"runtime,omitempty"` + DesiredState *InferenceServiceState `json:"desiredState,omitempty"` // ID of the `RegisteredModel` to serve. RegisteredModelId string `json:"registeredModelId"` // ID of the parent `ServingEnvironment` for this `InferenceService` entity. @@ -50,8 +50,8 @@ type InferenceService struct { // will change when the set of required properties is changed func NewInferenceService(registeredModelId string, servingEnvironmentId string) *InferenceService { this := InferenceService{} - var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED - this.State = &state + var desiredState InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.DesiredState = &desiredState this.RegisteredModelId = registeredModelId this.ServingEnvironmentId = servingEnvironmentId return &this @@ -62,8 +62,8 @@ func NewInferenceService(registeredModelId string, servingEnvironmentId string) // but it doesn't guarantee that properties required by API are set func NewInferenceServiceWithDefaults() *InferenceService { this := InferenceService{} - var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED - this.State = &state + var desiredState InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.DesiredState = &desiredState return &this } @@ -355,36 +355,36 @@ func (o *InferenceService) SetRuntime(v string) { o.Runtime = &v } -// GetState returns the State field value if set, zero value otherwise. -func (o *InferenceService) GetState() InferenceServiceState { - if o == nil || IsNil(o.State) { +// GetDesiredState returns the DesiredState field value if set, zero value otherwise. +func (o *InferenceService) GetDesiredState() InferenceServiceState { + if o == nil || IsNil(o.DesiredState) { var ret InferenceServiceState return ret } - return *o.State + return *o.DesiredState } -// GetStateOk returns a tuple with the State field value if set, nil otherwise +// GetDesiredStateOk returns a tuple with the DesiredState field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *InferenceService) GetStateOk() (*InferenceServiceState, bool) { - if o == nil || IsNil(o.State) { +func (o *InferenceService) GetDesiredStateOk() (*InferenceServiceState, bool) { + if o == nil || IsNil(o.DesiredState) { return nil, false } - return o.State, true + return o.DesiredState, true } -// HasState returns a boolean if a field has been set. -func (o *InferenceService) HasState() bool { - if o != nil && !IsNil(o.State) { +// HasDesiredState returns a boolean if a field has been set. +func (o *InferenceService) HasDesiredState() bool { + if o != nil && !IsNil(o.DesiredState) { return true } return false } -// SetState gets a reference to the given InferenceServiceState and assigns it to the State field. -func (o *InferenceService) SetState(v InferenceServiceState) { - o.State = &v +// SetDesiredState gets a reference to the given InferenceServiceState and assigns it to the DesiredState field. +func (o *InferenceService) SetDesiredState(v InferenceServiceState) { + o.DesiredState = &v } // GetRegisteredModelId returns the RegisteredModelId field value @@ -472,8 +472,8 @@ func (o InferenceService) ToMap() (map[string]interface{}, error) { if !IsNil(o.Runtime) { toSerialize["runtime"] = o.Runtime } - if !IsNil(o.State) { - toSerialize["state"] = o.State + if !IsNil(o.DesiredState) { + toSerialize["desiredState"] = o.DesiredState } toSerialize["registeredModelId"] = o.RegisteredModelId toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId diff --git a/pkg/openapi/model_inference_service_create.go b/pkg/openapi/model_inference_service_create.go index b4299de6..8724b96f 100644 --- a/pkg/openapi/model_inference_service_create.go +++ b/pkg/openapi/model_inference_service_create.go @@ -30,8 +30,8 @@ type InferenceServiceCreate struct { // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` // Model runtime. - Runtime *string `json:"runtime,omitempty"` - State *InferenceServiceState `json:"state,omitempty"` + Runtime *string `json:"runtime,omitempty"` + DesiredState *InferenceServiceState `json:"desiredState,omitempty"` // ID of the `RegisteredModel` to serve. RegisteredModelId string `json:"registeredModelId"` // ID of the parent `ServingEnvironment` for this `InferenceService` entity. @@ -44,8 +44,8 @@ type InferenceServiceCreate struct { // will change when the set of required properties is changed func NewInferenceServiceCreate(registeredModelId string, servingEnvironmentId string) *InferenceServiceCreate { this := InferenceServiceCreate{} - var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED - this.State = &state + var desiredState InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.DesiredState = &desiredState this.RegisteredModelId = registeredModelId this.ServingEnvironmentId = servingEnvironmentId return &this @@ -56,8 +56,8 @@ func NewInferenceServiceCreate(registeredModelId string, servingEnvironmentId st // but it doesn't guarantee that properties required by API are set func NewInferenceServiceCreateWithDefaults() *InferenceServiceCreate { this := InferenceServiceCreate{} - var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED - this.State = &state + var desiredState InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.DesiredState = &desiredState return &this } @@ -253,36 +253,36 @@ func (o *InferenceServiceCreate) SetRuntime(v string) { o.Runtime = &v } -// GetState returns the State field value if set, zero value otherwise. -func (o *InferenceServiceCreate) GetState() InferenceServiceState { - if o == nil || IsNil(o.State) { +// GetDesiredState returns the DesiredState field value if set, zero value otherwise. +func (o *InferenceServiceCreate) GetDesiredState() InferenceServiceState { + if o == nil || IsNil(o.DesiredState) { var ret InferenceServiceState return ret } - return *o.State + return *o.DesiredState } -// GetStateOk returns a tuple with the State field value if set, nil otherwise +// GetDesiredStateOk returns a tuple with the DesiredState field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *InferenceServiceCreate) GetStateOk() (*InferenceServiceState, bool) { - if o == nil || IsNil(o.State) { +func (o *InferenceServiceCreate) GetDesiredStateOk() (*InferenceServiceState, bool) { + if o == nil || IsNil(o.DesiredState) { return nil, false } - return o.State, true + return o.DesiredState, true } -// HasState returns a boolean if a field has been set. -func (o *InferenceServiceCreate) HasState() bool { - if o != nil && !IsNil(o.State) { +// HasDesiredState returns a boolean if a field has been set. +func (o *InferenceServiceCreate) HasDesiredState() bool { + if o != nil && !IsNil(o.DesiredState) { return true } return false } -// SetState gets a reference to the given InferenceServiceState and assigns it to the State field. -func (o *InferenceServiceCreate) SetState(v InferenceServiceState) { - o.State = &v +// SetDesiredState gets a reference to the given InferenceServiceState and assigns it to the DesiredState field. +func (o *InferenceServiceCreate) SetDesiredState(v InferenceServiceState) { + o.DesiredState = &v } // GetRegisteredModelId returns the RegisteredModelId field value @@ -361,8 +361,8 @@ func (o InferenceServiceCreate) ToMap() (map[string]interface{}, error) { if !IsNil(o.Runtime) { toSerialize["runtime"] = o.Runtime } - if !IsNil(o.State) { - toSerialize["state"] = o.State + if !IsNil(o.DesiredState) { + toSerialize["desiredState"] = o.DesiredState } toSerialize["registeredModelId"] = o.RegisteredModelId toSerialize["servingEnvironmentId"] = o.ServingEnvironmentId diff --git a/pkg/openapi/model_inference_service_update.go b/pkg/openapi/model_inference_service_update.go index af13e648..9442f917 100644 --- a/pkg/openapi/model_inference_service_update.go +++ b/pkg/openapi/model_inference_service_update.go @@ -28,8 +28,8 @@ type InferenceServiceUpdate struct { // ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. ModelVersionId *string `json:"modelVersionId,omitempty"` // Model runtime. - Runtime *string `json:"runtime,omitempty"` - State *InferenceServiceState `json:"state,omitempty"` + Runtime *string `json:"runtime,omitempty"` + DesiredState *InferenceServiceState `json:"desiredState,omitempty"` } // NewInferenceServiceUpdate instantiates a new InferenceServiceUpdate object @@ -38,8 +38,8 @@ type InferenceServiceUpdate struct { // will change when the set of required properties is changed func NewInferenceServiceUpdate() *InferenceServiceUpdate { this := InferenceServiceUpdate{} - var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED - this.State = &state + var desiredState InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.DesiredState = &desiredState return &this } @@ -48,8 +48,8 @@ func NewInferenceServiceUpdate() *InferenceServiceUpdate { // but it doesn't guarantee that properties required by API are set func NewInferenceServiceUpdateWithDefaults() *InferenceServiceUpdate { this := InferenceServiceUpdate{} - var state InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED - this.State = &state + var desiredState InferenceServiceState = INFERENCESERVICESTATE_DEPLOYED + this.DesiredState = &desiredState return &this } @@ -213,36 +213,36 @@ func (o *InferenceServiceUpdate) SetRuntime(v string) { o.Runtime = &v } -// GetState returns the State field value if set, zero value otherwise. -func (o *InferenceServiceUpdate) GetState() InferenceServiceState { - if o == nil || IsNil(o.State) { +// GetDesiredState returns the DesiredState field value if set, zero value otherwise. +func (o *InferenceServiceUpdate) GetDesiredState() InferenceServiceState { + if o == nil || IsNil(o.DesiredState) { var ret InferenceServiceState return ret } - return *o.State + return *o.DesiredState } -// GetStateOk returns a tuple with the State field value if set, nil otherwise +// GetDesiredStateOk returns a tuple with the DesiredState field value if set, nil otherwise // and a boolean to check if the value has been set. -func (o *InferenceServiceUpdate) GetStateOk() (*InferenceServiceState, bool) { - if o == nil || IsNil(o.State) { +func (o *InferenceServiceUpdate) GetDesiredStateOk() (*InferenceServiceState, bool) { + if o == nil || IsNil(o.DesiredState) { return nil, false } - return o.State, true + return o.DesiredState, true } -// HasState returns a boolean if a field has been set. -func (o *InferenceServiceUpdate) HasState() bool { - if o != nil && !IsNil(o.State) { +// HasDesiredState returns a boolean if a field has been set. +func (o *InferenceServiceUpdate) HasDesiredState() bool { + if o != nil && !IsNil(o.DesiredState) { return true } return false } -// SetState gets a reference to the given InferenceServiceState and assigns it to the State field. -func (o *InferenceServiceUpdate) SetState(v InferenceServiceState) { - o.State = &v +// SetDesiredState gets a reference to the given InferenceServiceState and assigns it to the DesiredState field. +func (o *InferenceServiceUpdate) SetDesiredState(v InferenceServiceState) { + o.DesiredState = &v } func (o InferenceServiceUpdate) MarshalJSON() ([]byte, error) { @@ -270,8 +270,8 @@ func (o InferenceServiceUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.Runtime) { toSerialize["runtime"] = o.Runtime } - if !IsNil(o.State) { - toSerialize["state"] = o.State + if !IsNil(o.DesiredState) { + toSerialize["desiredState"] = o.DesiredState } return toSerialize, nil } From eaaae5966cb8b2e56d9f32a3eecaf9bb0ada4216 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 15 Dec 2023 16:36:40 +0100 Subject: [PATCH 195/254] Fix rest params order (#245) --- internal/server/openapi/api_model_registry_service_service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index f9472c61..4d617174 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -185,7 +185,7 @@ func (s *ModelRegistryServiceAPIService) FindInferenceService(ctx context.Contex // FindModelArtifact - Get a ModelArtifact that matches search parameters. func (s *ModelRegistryServiceAPIService) FindModelArtifact(ctx context.Context, name string, externalID string, parentResourceID string) (ImplResponse, error) { - result, err := s.coreApi.GetModelArtifactByParams(&name, &externalID, &parentResourceID) + result, err := s.coreApi.GetModelArtifactByParams(&name, &parentResourceID, &externalID) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } @@ -197,7 +197,7 @@ func (s *ModelRegistryServiceAPIService) FindModelArtifact(ctx context.Context, // FindModelVersion - Get a ModelVersion that matches search parameters. func (s *ModelRegistryServiceAPIService) FindModelVersion(ctx context.Context, name string, externalID string, registeredModelID string) (ImplResponse, error) { - result, err := s.coreApi.GetModelVersionByParams(&name, &externalID, ®isteredModelID) + result, err := s.coreApi.GetModelVersionByParams(&name, ®isteredModelID, &externalID) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } From b19176f1c85be57d03a0ebfe8a470cee7eadc13b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 09:49:50 +0000 Subject: [PATCH 196/254] build(deps): bump google.golang.org/grpc from 1.59.0 to 1.60.0 (#247) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6e938995..901dd465 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/spf13/viper v1.18.1 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 - google.golang.org/grpc v1.59.0 + google.golang.org/grpc v1.60.0 google.golang.org/protobuf v1.31.0 ) diff --git a/go.sum b/go.sum index 394d921e..e02ff67b 100644 --- a/go.sum +++ b/go.sum @@ -227,8 +227,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= +google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From c52b1882803fbfa25f14f1f3ba1802b1251b0be0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 09:50:54 +0000 Subject: [PATCH 197/254] build(deps): bump actions/upload-artifact from 3 to 4 (#250) --- .github/workflows/python-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 5dd07670..7f74c350 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -81,7 +81,7 @@ jobs: - name: Upload documentation if: matrix.session == 'docs-build' - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: docs path: clients/python/docs/_build From e9b0e9d3698e4114a2e6b7639d3ed65cf252d969 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 Dec 2023 09:51:58 +0000 Subject: [PATCH 198/254] build(deps): bump github.com/google/uuid from 1.4.0 to 1.5.0 (#248) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 901dd465..c34345f9 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.5.0 github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.17.0 // indirect diff --git a/go.sum b/go.sum index e02ff67b..b1608531 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= +github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= From 77b889df56f8979d94382bebfbdf329cfc96e95f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 Dec 2023 10:11:54 +0100 Subject: [PATCH 199/254] build(deps): bump github.com/containerd/containerd from 1.7.7 to 1.7.11 (#253) Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.7.7 to 1.7.11. - [Release notes](https://github.com/containerd/containerd/releases) - [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md) - [Commits](https://github.com/containerd/containerd/compare/v1.7.7...v1.7.11) --- updated-dependencies: - dependency-name: github.com/containerd/containerd dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index c34345f9..278f9c81 100644 --- a/go.mod +++ b/go.mod @@ -31,9 +31,9 @@ require ( dario.cat/mergo v1.0.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect - github.com/Microsoft/hcsshim v0.11.1 // indirect + github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/containerd/containerd v1.7.7 // indirect + github.com/containerd/containerd v1.7.11 // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.7+incompatible // indirect diff --git a/go.sum b/go.sum index b1608531..be875c7f 100644 --- a/go.sum +++ b/go.sum @@ -6,15 +6,15 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= -github.com/Microsoft/hcsshim v0.11.1 h1:hJ3s7GbWlGK4YVV92sO88BQSyF4ZLVy7/awqOlPxFbA= -github.com/Microsoft/hcsshim v0.11.1/go.mod h1:nFJmaO4Zr5Y7eADdFOpYswDDlNVbvcIJJNJLECr5JQg= +github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= +github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.7.7 h1:QOC2K4A42RQpcrZyptP6z9EJZnlHfHJUfZrAAHe15q4= -github.com/containerd/containerd v1.7.7/go.mod h1:3c4XZv6VeT9qgf9GMTxNTMFxGJrGpI2vz1yk4ye+YY8= +github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= +github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= From dc5da9b7b2f65aadbd8c026b7d5956daae37defb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 13:37:51 +0100 Subject: [PATCH 200/254] build(deps): bump github.com/go-chi/chi/v5 from 5.0.10 to 5.0.11 (#255) Bumps [github.com/go-chi/chi/v5](https://github.com/go-chi/chi) from 5.0.10 to 5.0.11. - [Release notes](https://github.com/go-chi/chi/releases) - [Changelog](https://github.com/go-chi/chi/blob/master/CHANGELOG.md) - [Commits](https://github.com/go-chi/chi/compare/v5.0.10...v5.0.11) --- updated-dependencies: - dependency-name: github.com/go-chi/chi/v5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 278f9c81..554f21fa 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/opendatahub-io/model-registry go 1.19 require ( - github.com/go-chi/chi/v5 v5.0.10 + github.com/go-chi/chi/v5 v5.0.11 github.com/go-chi/cors v1.2.1 github.com/golang/glog v1.2.0 github.com/spf13/cobra v1.8.0 diff --git a/go.sum b/go.sum index be875c7f..20342a6c 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,8 @@ github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= -github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA= +github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= From 807e605b426f054edf595d04f4b318efa8e1eba9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 14:54:46 +0100 Subject: [PATCH 201/254] build(deps): bump github.com/spf13/viper from 1.18.1 to 1.18.2 (#257) Bumps [github.com/spf13/viper](https://github.com/spf13/viper) from 1.18.1 to 1.18.2. - [Release notes](https://github.com/spf13/viper/releases) - [Commits](https://github.com/spf13/viper/compare/v1.18.1...v1.18.2) --- updated-dependencies: - dependency-name: github.com/spf13/viper dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 554f21fa..c452bfca 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/golang/glog v1.2.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.18.1 + github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 google.golang.org/grpc v1.60.0 diff --git a/go.sum b/go.sum index 20342a6c..5ea53b38 100644 --- a/go.sum +++ b/go.sum @@ -137,8 +137,8 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.1 h1:rmuU42rScKWlhhJDyXZRKJQHXFX02chSVW1IvkPGiVM= -github.com/spf13/viper v1.18.1/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= +github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= From 7a89412e3cce9d043f0cffb81a0cd3da1ef1ee5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 14:58:49 +0100 Subject: [PATCH 202/254] build(deps): bump google.golang.org/grpc from 1.60.0 to 1.60.1 (#258) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.60.0 to 1.60.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.60.0...v1.60.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c452bfca..d28f54e2 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 - google.golang.org/grpc v1.60.0 + google.golang.org/grpc v1.60.1 google.golang.org/protobuf v1.31.0 ) diff --git a/go.sum b/go.sum index 5ea53b38..270be6be 100644 --- a/go.sum +++ b/go.sum @@ -227,8 +227,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= -google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From 53b744622382220d7fd827f52ba74f4d99b0319b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jan 2024 15:03:04 +0100 Subject: [PATCH 203/254] build(deps): bump google.golang.org/protobuf from 1.31.0 to 1.32.0 (#259) Bumps google.golang.org/protobuf from 1.31.0 to 1.32.0. --- updated-dependencies: - dependency-name: google.golang.org/protobuf dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d28f54e2..66250a1a 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 google.golang.org/grpc v1.60.1 - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.32.0 ) require ( diff --git a/go.sum b/go.sum index 270be6be..50b6b08b 100644 --- a/go.sum +++ b/go.sum @@ -232,8 +232,8 @@ google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= From 0deba861bd65f8131a1b64a5db89ffa86b52646e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Jan 2024 11:15:16 +0100 Subject: [PATCH 204/254] build(deps-dev): bump jinja2 from 3.1.2 to 3.1.3 in /clients/python (#264) Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/pallets/jinja/releases) - [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) - [Commits](https://github.com/pallets/jinja/compare/3.1.2...3.1.3) --- updated-dependencies: - dependency-name: jinja2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- clients/python/poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock index 6564f886..cd410389 100644 --- a/clients/python/poetry.lock +++ b/clients/python/poetry.lock @@ -456,13 +456,13 @@ files = [ [[package]] name = "jinja2" -version = "3.1.2" +version = "3.1.3" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" files = [ - {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, - {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, ] [package.dependencies] From 97a976bffe2e533f75a93aec82e8747284765ba0 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Mon, 15 Jan 2024 16:05:43 +0100 Subject: [PATCH 205/254] ADR: Remote-only packaging of MLMD Python lib (#261) * ADR: Remote-only packaging of MLMD Python lib * Update doc/remote_only_packaging_of_MLMD_Python_lib.md Co-authored-by: Andrea Lamparelli * Update doc/remote_only_packaging_of_MLMD_Python_lib.md Co-authored-by: Isabella Basso * Update doc/remote_only_packaging_of_MLMD_Python_lib.md Co-authored-by: Isabella Basso * Update doc/remote_only_packaging_of_MLMD_Python_lib.md Co-authored-by: Isabella Basso * Update doc/remote_only_packaging_of_MLMD_Python_lib.md Co-authored-by: Isabella Basso * rework sections aligning to review comments * Update doc/remote_only_packaging_of_MLMD_Python_lib.md Co-authored-by: Isabella Basso --------- Co-authored-by: Andrea Lamparelli Co-authored-by: Isabella Basso --- ...emote_only_packaging_of_MLMD_Python_lib.md | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 doc/remote_only_packaging_of_MLMD_Python_lib.md diff --git a/doc/remote_only_packaging_of_MLMD_Python_lib.md b/doc/remote_only_packaging_of_MLMD_Python_lib.md new file mode 100644 index 00000000..8d4abde9 --- /dev/null +++ b/doc/remote_only_packaging_of_MLMD_Python_lib.md @@ -0,0 +1,126 @@ +# Remote-only packaging of MLMD Python lib + +## Context and Problem statement + +Google’s ML Metadata (MLMD) is a project composed of a C++ server, and a Python client library. +The server exposes a gRPC interface, and is only distributed for x86-64 architectures. +It is embedded in the client's wheel binary, providing an additional convenience [method for running the server locally (in memory)](https://www.tensorflow.org/tfx/guide/mlmd#metadata_storage_backends_and_store_connection_configuration), +whilst also making it [architecture specific](https://pypi.org/project/ml-metadata/1.14.0/#files). + +The [Model Registry project](https://docs.google.com/document/d/1G-pjdGaS2kLELsB5kYk_D4AmH-fTfnCnJOhJ8xENjx0/edit?usp=sharing) (MR) is built on top of MLMD. +The Go implementation interfaces with the MLMD server via gRPC, typically available as a Docker container. +The [MR Python client](https://github.com/opendatahub-io/model-registry/tree/main/clients/python#readme) wraps the MLMD client. + +As the MLMD client is architecture specific, so is the MR Python client, which **severely limits the targets it can run on**, as it only supports x86-64. +This **poses many challenges to contributors** using other CPU architectures, specially ARM, as that's become more prevalent in recent years. + +Since the Model Registry python client does _not_ leverage the embedded MLMD server's in-memory connection, we present options for a “soft-fork” and re-distribution of the MLMD client as a pure Python library, making it platform/architecture agnostic. + +The resulting artifact, a MLMD python wheel supporting only remote gRPC connections at the same time being a “pure library” hence not requiring specific CPU architectures, OSes, or CPython versions, could be as well published on PyPI under the ODH org, and become the dependency of [MR python client](/clients/python/README.md). + + +## Goals + +* consider required changes to “soft-fork” MLMD wheel to support only remote gRPC connections +* repackaging as a pure library + + +## Non-Goals + +* “hard”-fork of MLMD +* maintaining original MLMD tests (those bound to embedded server) + + +## Proposed solution + +Refer to the conclusions section for the motivations behind selecting: +1. soft-fork upstream repo, modify pip+bazel build, to produce the distributable Python client ("Alternative B", below) +2. create a `ml-metadata-remote` or similarly named package on PyPI based on the distributable wheel and files from the step1 above ("Packaging Option1", below) + +For documentation purposes, the exploration of the different alternatives is reported below. + + +## Alternative A: repackage the resulting wheel + +This solution explores the steps required to simply repackage the existing and distributed (by Google) MLMD python wheel, removing all embedded binaries, and repackaging the wheel as a pure library. + +This has been experimented with success on this repository: ([link](https://github.com/tarilabs/ml-metadata-remote)) + +The steps required are recorded here: ([link](https://github.com/tarilabs/ml-metadata-remote/commits/v1.14.0)) + +and mainly consists of: + +1. Download one platform-specific MLMD v1.14.0 wheel and extract its content ([reference](https://github.com/tarilabs/ml-metadata-remote/commit/39dd0c7dcd063e0440a6354017445dada8423f0c#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5)) +2. Remove embedded code, apply required code changes ([reference](https://github.com/tarilabs/ml-metadata-remote/commit/bcb1f0ffd37600e056342aff39e154bb35422668#diff-f363c85a1cf3536a48a7b721b02a6999b80a08b9c305d185327e87e2769b6f21)) +3. Recompute dist-info checksums before repackaging ([reference](https://github.com/tarilabs/ml-metadata-remote/commit/fda125fb742ab8ecf4a7153705717d8b50f59326#diff-53bdc596caf062825dbb42b65e5b2305db70d2e533c03bc677b13cc8c7cfd236)) +4. Repackage the directories as a new pure library wheel ([reference](https://github.com/tarilabs/ml-metadata-remote/commit/5d199f808eea0cb7ba78a0702be8de3306477df8)) + +The resulting artifact has been [tested](https://github.com/tarilabs/ml-metadata-remote#readme:~:text=Testing%20with%20launching%20a%20local%20server) locally with a gRPC connection to MLMD server made available via Docker. The resulting artifact is directly available for local download: ([link](https://github.com/tarilabs/ml-metadata-remote/releases/tag/1.14.0)) + + +## Alternative B: build by soft-fork upstream repo + +This solution explores how to use the upstream MLMD repo by Google and by making necessary code changes, so to directly produce with the pip+bazel build the wheel as a pure library. + +This has been experimented with success on this fork: ([link](https://github.com/tarilabs/ml-metadata/commits/remote-r1.14.0)) + +The steps required mainly consists of: + +1. Make changes to the bazel BUILD file ([reference](https://github.com/tarilabs/ml-metadata/commit/079aeb3a9da69eb960e428a7866e279d0bfb533b#diff-c8858dec4f58c1d8a280af8c117ff8480f7ed4ae863b96e1ba20b52f83222aab)) +2. Make changes to sh build script ([reference](https://github.com/tarilabs/ml-metadata/commit/079aeb3a9da69eb960e428a7866e279d0bfb533b#diff-125a2f247ce39f711e1c8a77f430bd5b1b865cd10b5c5fef0d9140d276c617f2)) +3. Make changes to setup.py build file ([reference](https://github.com/tarilabs/ml-metadata/commit/079aeb3a9da69eb960e428a7866e279d0bfb533b#diff-60f61ab7a8d1910d86d9fda2261620314edcae5894d5aaa236b821c7256badd7)) +4. Apply required code changes analogously to “Alternative A” (see other changes in [this commit](https://github.com/tarilabs/ml-metadata/commit/079aeb3a9da69eb960e428a7866e279d0bfb533b)) + +The resulting artifact has been [tested](https://github.com/tarilabs/ml-metadata/commit/794ec39d97e3ac70db2ca18fcf5807c44f339f0b) locally with a gRPC connection to MLMD server made available via Docker, similar to instructions provided in “Alternative A”. + + +## Packaging + +In this section we consider packaging and delivery options for the resulting artifact from the alternative selected above. + + +### Packaging Option1: separate repo on ODH + +This delivery option considers having a separate repo on ODH, called “ml-metadata-remote” (or the likes). Repeat the exercise from the alternative selected above on this repo. Then deliver this as a package on PyPI. + +Pros: + +* Well isolated dependency + * also, if one day upstream Google MLMD resolves to be platform/arch agnostic, is just a matter of changing again the consumed dependency from MR python client +* Google code (copyright header) is isolated from Model Registry code +* The resulting artifact could also be re-used by other communities/users + +Cons: + +* Additional artifact to publish on PyPI + + +### Packaging Option2: mix resulting artifact inside Model Registry repo + +This delivery option considers placing the resulting artifact by executing the exercise from the alternative selected above and placing it directly inside the Model Registry repo, with the python client source [location](https://github.com/opendatahub-io/model-registry/tree/main/clients/python). (for analogy, this is similar to “shading”/”uberjar” in Java world for those familiar with the concept) + +Pros: + +* Only one artifact to publish on PyPI + +Cons: + +* Google code (copyright header) is mixed with Model Registry code + * at this stage is not clear if any implications with uplifting the MR project in KF community +* The resulting artifact cannot be re-used by other communities/users +* If one day upstream Google MLMD resolves to be platform/arch agnostic, changing back the MR python client to use the original ml-metadata could require extra work and effort + + +## Conclusion + +Based on analysis of the alternatives provided, we decided to further pursue: +- the repackaging by **Alternative B** because makes it actually easier to demonstrate the steps and modifications required using as baseline the upstream repo. +- the distribution by **Packaging Option1** because it will make it easier to "revert" to the upstream `ml-metadata` dependency if upstream will publish for all architectures, OSes, etc. and as the pros outweight considered cons. + +MR python client [tests](https://github.com/opendatahub-io/model-registry/blob/259b39320953bf05942dcec1fb5ec74f7eb5d4a7/clients/python/tests/conftest.py#L19) should be rewritten using Testcontainers, and not leveraging the embedded server (already done with [this PR](https://github.com/opendatahub-io/model-registry/pull/225)). + +The group concur this is a sensible approach ([recorded here](https://redhat-internal.slack.com/archives/C05LGBNUK9C/p1700763823505259?thread_ts=1700427888.670999&cid=C05LGBNUK9C)). + +This change would also better align the test approach used for the MR python client, by aligning with the same strategy of the MR core Go layer test framework, which already makes use of Testcontainers for Go ([reference](https://github.com/opendatahub-io/model-registry/blob/259b39320953bf05942dcec1fb5ec74f7eb5d4a7/internal/testutils/test_container_utils.go#L59)). + +This would allow to update the constraint on the version for the `attrs` dependency as part of this activity. From 32b2bfc5fa906464f92747985309077ce5bc8286 Mon Sep 17 00:00:00 2001 From: Radim Kubis Date: Wed, 17 Jan 2024 14:38:55 +0100 Subject: [PATCH 206/254] New(workflow): Run Robot Framework tests with every push (#208) * New(workflow): Run Robot Framework tests with every push Co-authored-by: Andrea Lamparelli --- .github/workflows/run-robot-tests.yaml | 65 ++++++++++++++++++++++++++ test/robot/requirements.txt | 4 ++ 2 files changed, 69 insertions(+) create mode 100644 .github/workflows/run-robot-tests.yaml create mode 100644 test/robot/requirements.txt diff --git a/.github/workflows/run-robot-tests.yaml b/.github/workflows/run-robot-tests.yaml new file mode 100644 index 00000000..03135217 --- /dev/null +++ b/.github/workflows/run-robot-tests.yaml @@ -0,0 +1,65 @@ +name: run-robot-tests +run-name: Run Robot Framework tests +# Run workflow +on: + # For every push to repository + push: + # To any branch + branches: + - '*' + # For every pull request + pull_request: + # But ignore this paths + paths-ignore: + - 'LICENSE*' + - 'DOCKERFILE*' + - '**.gitignore' + - '**.md' + - '**.txt' + - '.github/ISSUE_TEMPLATE/**' + - '.github/dependabot.yml' + - 'docs/**' + - 'scripts/**' +# Define workflow jobs +jobs: + # Job runs Robot Framework tests against locally build image from current code + run-robot-tests: + # Ubuntu latest is sufficient system for run + runs-on: ubuntu-latest + # Define steps of job + steps: + # Get checkout action to get this repository + - uses: actions/checkout@v4 + # Install defined Python version to run Robot Framework tests + - name: Install Python 3.9.x + # Get setup-python action to install Python + uses: actions/setup-python@v4 + with: + # Set Python version to install + python-version: '3.9' + # Set architecture of Python to install + architecture: 'x64' + # Install required Python packages for running Robot Framework tests + - name: Install required Python packages + # Install required Python packages using pip + run: pip install -r test/robot/requirements.txt + # Install model_registry Python package from current code + - name: Install model_registry Python package + # Install model_registry package as editable using pip + run: pip install -e clients/python + # Start docker compose with locally build image from current code + - name: Start docker compose with local image + # Start docker compose in the background + run: docker compose -f docker-compose-local.yaml up --detach + # Run Robot Framework tests in REST mode against running docker compose + - name: Run Robot Framework tests (REST mode) + # Run Robot Framework tests in REST mode from test/robot directory + run: robot test/robot + # Run Robot Framework tests in Python mode against running docker compose + - name: Run Robot Framework tests (Python mode) + # Run Robot Framework tests in Python mode from test/robot directory + run: TEST_MODE=Python robot test/robot/MRandLogicalModel.robot + # Shutdown docker compose with locally build image from current code + - name: Shutdown docker compose with local image + # Shutdown docker compose running in the background + run: docker compose -f docker-compose-local.yaml down \ No newline at end of file diff --git a/test/robot/requirements.txt b/test/robot/requirements.txt new file mode 100644 index 00000000..bd24f3c1 --- /dev/null +++ b/test/robot/requirements.txt @@ -0,0 +1,4 @@ +ml-metadata==1.14.0 +robotframework +robotframework-requests +pyyaml \ No newline at end of file From 4944d7b640929e6bba0953658638908bf63ef750 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 3 Jan 2024 19:20:59 -0300 Subject: [PATCH 207/254] py: client: fix return types and docstrings Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/_client.py | 69 +++++++++++-------- clients/python/src/model_registry/core.py | 27 +++++--- .../src/model_registry/store/wrapper.py | 4 +- clients/python/tests/test_client.py | 13 ++-- clients/python/tests/test_core.py | 37 ++++++---- 5 files changed, 89 insertions(+), 61 deletions(-) diff --git a/clients/python/src/model_registry/_client.py b/clients/python/src/model_registry/_client.py index 4376deaa..6b545b56 100644 --- a/clients/python/src/model_registry/_client.py +++ b/clients/python/src/model_registry/_client.py @@ -21,12 +21,12 @@ def __init__( """Constructor. Args: - server_address (str): Server address. - port (int): Server port. - author (str): Name of the author. - client_key (str, optional): The PEM-encoded private key as a byte string. - server_cert (str, optional): The PEM-encoded certificate as a byte string. - custom_ca (str, optional): The PEM-encoded root certificates as a byte string. + server_address: Server address. + port: Server port. + author: Name of the author. + client_key: The PEM-encoded private key as a byte string. + server_cert: The PEM-encoded certificate as a byte string. + custom_ca: The PEM-encoded root certificates as a byte string. """ # TODO: get args from env self._author = author @@ -77,24 +77,23 @@ def register_model( ) -> RegisteredModel: """Register a model. - Version has to be unique for the model. Either `storage_key` and `storage_path`, or `service_account_name` must be provided. Args: - name (str): Name of the model. - uri (str): URI of the model. + name: Name of the model. + uri: URI of the model. Keyword Args: - model_format_name (str): Name of the model format. - model_format_version (str): Version of the model format. - version (str): Version of the model. - description (str, optional): Description of the model. - storage_key (str, optional): Storage key. - storage_path (str, optional): Storage path. - service_account_name (str, optional): Service account name. + model_format_name: Name of the model format. + model_format_version: Version of the model format. + version: Version of the model. Has to be unique. + description: Description of the model. + storage_key: Storage key. + storage_path: Storage path. + service_account_name: Service account name. Returns: - RegisteredModel: Registered model. + Registered model. """ rm = self._register_model(name) mv = self._register_new_version(rm, version, description=description) @@ -110,39 +109,49 @@ def register_model( return rm - def get_registered_model(self, name: str) -> RegisteredModel: + def get_registered_model(self, name: str) -> RegisteredModel | None: """Get a registered model. Args: - name (str): Name of the model. + name: Name of the model. Returns: - RegisteredModel: Registered model. + Registered model. """ return self._api.get_registered_model_by_params(name) - def get_model_version(self, name: str, version: str) -> ModelVersion: + def get_model_version(self, name: str, version: str) -> ModelVersion | None: """Get a model version. Args: - name (str): Name of the model. - version (str): Version of the model. + name: Name of the model. + version: Version of the model. Returns: - ModelVersion: Model version. + Model version. + + Raises: + StoreException: If the model does not exist. """ - rm = self._api.get_registered_model_by_params(name) + if not (rm := self._api.get_registered_model_by_params(name)): + msg = f"Model {name} does not exist" + raise StoreException(msg) return self._api.get_model_version_by_params(rm.id, version) - def get_model_artifact(self, name: str, version: str) -> ModelArtifact: + def get_model_artifact(self, name: str, version: str) -> ModelArtifact | None: """Get a model artifact. Args: - name (str): Name of the model. - version (str): Version of the model. + name: Name of the model. + version: Version of the model. Returns: - ModelArtifact: Model artifact. + Model artifact. + + Raises: + StoreException: If either the model or the version don't exist. """ - mv = self.get_model_version(name, version) + if not (mv := self.get_model_version(name, version)): + msg = f"Version {version} does not exist" + raise StoreException(msg) return self._api.get_model_artifact_by_params(mv.id) diff --git a/clients/python/src/model_registry/core.py b/clients/python/src/model_registry/core.py index 66c04829..84f5b1fa 100644 --- a/clients/python/src/model_registry/core.py +++ b/clients/python/src/model_registry/core.py @@ -111,6 +111,9 @@ def get_registered_model_by_params( Returns: Registered model. + + Raises: + StoreException: If neither name nor external ID is provided. """ if name is None and external_id is None: msg = "Either name or external_id must be provided" @@ -173,7 +176,7 @@ def upsert_model_version( ) return id - def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: + def get_model_version_by_id(self, model_version_id: str) -> ModelVersion | None: """Fetch a model version by its ID. Args: @@ -192,7 +195,7 @@ def get_model_version_by_id(self, model_version_id: str) -> ModelVersion: def get_model_versions( self, registered_model_id: str, options: ListOptions | None = None - ) -> list[ModelVersion]: + ) -> Sequence[ModelVersion]: """Fetch model versions by registered model ID. Args: @@ -228,6 +231,9 @@ def get_model_version_by_params( Returns: Model version. + + Raises: + StoreException: If neither external ID nor registered model ID and version is provided. """ if external_id is not None: proto_mv = self._store.get_context( @@ -262,17 +268,17 @@ def upsert_model_artifact( Returns: ID of the model artifact. + + Raises: + StoreException: If the model version already has a model artifact. """ mv_id = int(model_version_id) - try: - self._store.get_attributed_artifact( - ModelArtifact.get_proto_type_name(), mv_id - ) + if self._store.get_attributed_artifact( + ModelArtifact.get_proto_type_name(), mv_id + ): msg = f"Model version with ID {mv_id} already has a model artifact" raise StoreException(msg) - except StoreException as e: - if "found" not in str(e).lower(): - raise + model_artifact._model_version_id = model_version_id id = self._store.put_artifact(self._map(model_artifact)) self._store.put_attribution(mv_id, id) @@ -315,6 +321,9 @@ def get_model_artifact_by_params( Returns: Model artifact. + + Raises: + StoreException: If neither external ID nor model version ID is provided. """ if external_id: proto_ma = self._store.get_artifact( diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index 50056d80..ff195d76 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -317,8 +317,8 @@ def get_attributed_artifact(self, art_type_name: str, ctx_id: int) -> Artifact: artifacts = self._filter_type(art_type_name, artifacts) if artifacts: return artifacts[0] - msg = "No artifacts found" - raise StoreException(msg) + + return None def get_artifacts( self, art_type_name: str, options: ListOptions diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 1f5f5dfb..dd6fa2d1 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -55,11 +55,14 @@ def test_get(mr_client: ModelRegistry): version=version, ) - assert rm.id == mr_client.get_registered_model(name).id + assert (_rm := mr_client.get_registered_model(name)) + assert rm.id == _rm.id mr_api = mr_client._api - mv = mr_api.get_model_version_by_params(rm.id, version) - ma = mr_api.get_model_artifact_by_params(mv.id) + assert (mv := mr_api.get_model_version_by_params(rm.id, version)) + assert (ma := mr_api.get_model_artifact_by_params(mv.id)) - assert mv.id == mr_client.get_model_version(name, version).id - assert ma.id == mr_client.get_model_artifact(name, version).id + assert (_mv := mr_client.get_model_version(name, version)) + assert mv.id == _mv.id + assert (_ma := mr_client.get_model_artifact(name, version)) + assert ma.id == _ma.id diff --git a/clients/python/tests/test_core.py b/clients/python/tests/test_core.py index f509107d..bdb3ba14 100644 --- a/clients/python/tests/test_core.py +++ b/clients/python/tests/test_core.py @@ -75,7 +75,7 @@ def test_get_registered_model_by_id( ): rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] - mlmd_rm = mr_api.get_registered_model_by_id(str(rm_id)) + assert (mlmd_rm := mr_api.get_registered_model_by_id(str(rm_id))) assert mlmd_rm.id == str(rm_id) assert mlmd_rm.name == registered_model.py.name assert mlmd_rm.name == registered_model.proto.name @@ -87,7 +87,9 @@ def test_get_registered_model_by_name( ): rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] - mlmd_rm = mr_api.get_registered_model_by_params(name=registered_model.py.name) + assert ( + mlmd_rm := mr_api.get_registered_model_by_params(name=registered_model.py.name) + ) assert mlmd_rm.id == str(rm_id) assert mlmd_rm.name == registered_model.py.name assert mlmd_rm.name == registered_model.proto.name @@ -101,8 +103,10 @@ def test_get_registered_model_by_external_id( registered_model.proto.external_id = "external_id" rm_id = mr_api._store._mlmd_store.put_contexts([registered_model.proto])[0] - mlmd_rm = mr_api.get_registered_model_by_params( - external_id=registered_model.py.external_id + assert ( + mlmd_rm := mr_api.get_registered_model_by_params( + external_id=registered_model.py.external_id + ) ) assert mlmd_rm.id == str(rm_id) assert mlmd_rm.name == registered_model.py.name @@ -144,7 +148,7 @@ def test_get_model_version_by_id(mr_api: ModelRegistryAPIClient, model_version: ctx_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] id = str(ctx_id) - mlmd_mv = mr_api.get_model_version_by_id(id) + assert (mlmd_mv := mr_api.get_model_version_by_id(id)) assert mlmd_mv.id == id assert mlmd_mv.name == model_version.py.name assert mlmd_mv.version != model_version.proto.name @@ -156,8 +160,10 @@ def test_get_model_version_by_name( model_version.proto.name = f"1:{model_version.proto.name}" mv_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] - mlmd_mv = mr_api.get_model_version_by_params( - registered_model_id="1", version=model_version.py.name + assert ( + mlmd_mv := mr_api.get_model_version_by_params( + registered_model_id="1", version=model_version.py.name + ) ) assert mlmd_mv.id == str(mv_id) assert mlmd_mv.name == model_version.py.name @@ -172,8 +178,10 @@ def test_get_model_version_by_external_id( model_version.py.external_id = "external_id" mv_id = mr_api._store._mlmd_store.put_contexts([model_version.proto])[0] - mlmd_mv = mr_api.get_model_version_by_params( - external_id=model_version.py.external_id + assert ( + mlmd_mv := mr_api.get_model_version_by_params( + external_id=model_version.py.external_id + ) ) assert mlmd_mv.id == str(mv_id) assert mlmd_mv.name == model_version.py.name @@ -266,8 +274,7 @@ def test_get_model_artifact_by_id(mr_api: ModelRegistryAPIClient, model: Mapped) id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] id = str(id) - mlmd_ma = mr_api.get_model_artifact_by_id(id) - + assert (mlmd_ma := mr_api.get_model_artifact_by_id(id)) assert mlmd_ma.id == id assert mlmd_ma.name == model.py.name assert mlmd_ma.name != model.proto.name @@ -285,8 +292,7 @@ def test_get_model_artifact_by_model_version_id( [Attribution(context_id=mv_id, artifact_id=ma_id)], [] ) - mlmd_ma = mr_api.get_model_artifact_by_params(model_version_id=str(mv_id)) - + assert (mlmd_ma := mr_api.get_model_artifact_by_params(model_version_id=str(mv_id))) assert mlmd_ma.id == str(ma_id) assert mlmd_ma.name == model.py.name assert mlmd_ma.name != model.proto.name @@ -302,8 +308,9 @@ def test_get_model_artifact_by_external_id( id = mr_api._store._mlmd_store.put_artifacts([model.proto])[0] id = str(id) - mlmd_ma = mr_api.get_model_artifact_by_params(external_id=model.py.external_id) - + assert ( + mlmd_ma := mr_api.get_model_artifact_by_params(external_id=model.py.external_id) + ) assert mlmd_ma.id == id assert mlmd_ma.name == model.py.name assert mlmd_ma.name != model.proto.name From 7adacc2d11bf56ef5b20b677ccc8648a56e28927 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 3 Jan 2024 19:20:59 -0300 Subject: [PATCH 208/254] py: contexts: fix MV prefix type Signed-off-by: Isabella Basso do Amaral --- clients/python/src/model_registry/core.py | 5 ++--- clients/python/src/model_registry/types/contexts.py | 4 ++-- clients/python/tests/types/test_context_mapping.py | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/clients/python/src/model_registry/core.py b/clients/python/src/model_registry/core.py index 84f5b1fa..270d89b8 100644 --- a/clients/python/src/model_registry/core.py +++ b/clients/python/src/model_registry/core.py @@ -160,11 +160,10 @@ def upsert_model_version( Returns: ID of the model version. """ - rm_id = int(registered_model_id) # this is not ideal but we need this info for the prefix - model_version._registered_model_id = rm_id + model_version._registered_model_id = registered_model_id id = self._store.put_context(self._map(model_version)) - self._store.put_context_parent(rm_id, id) + self._store.put_context_parent(int(registered_model_id), id) new_py_mv = ModelVersion.unmap( self._store.get_context(ModelVersion.get_proto_type_name(), id) ) diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 6b452ae9..97d605fc 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -86,14 +86,14 @@ class ModelVersion(BaseContext, Prefixable): tags: list[str] = field(init=False, factory=list) metadata: dict[str, ScalarType] = field(init=False, factory=dict) - _registered_model_id: int | None = field(init=False, default=None) + _registered_model_id: str | None = field(init=False, default=None) def __attrs_post_init__(self) -> None: self.name = self.version @property @override - def mlmd_name_prefix(self): + def mlmd_name_prefix(self) -> str: assert ( self._registered_model_id is not None ), "There's no registered model associated with this version" diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index 5d01b0e9..50e95a8d 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -34,7 +34,7 @@ def full_model_version() -> Mapped: external_id="test_external_id", description="test description", ) - py_version._registered_model_id = 1 + py_version._registered_model_id = "1" py_version.tags = ["test_tag1", "test_tag2"] py_version.metadata = { "int_key": 1, @@ -56,7 +56,7 @@ def minimal_model_version() -> Mapped: proto_version.properties["state"].string_value = "LIVE" py_version = ModelVersion("test_model", "1.0.0", "test_author") - py_version._registered_model_id = 1 + py_version._registered_model_id = "1" return Mapped(proto_version, py_version) From 622ce611c03f41e1ef38e025a73ba63f77d47850 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 3 Jan 2024 19:20:59 -0300 Subject: [PATCH 209/254] py: ctx: remove tags prop As discussed on [1], there's no need for a tags property just yet, and there's also no agreed format for list metadata, so let's just get rid of it. [1]: https://github.com/opendatahub-io/model-registry/pull/260#discussion_r1441786749 Signed-off-by: Isabella Basso do Amaral --- .../src/model_registry/types/contexts.py | 15 +++---- clients/python/tests/conftest.py | 41 +++++++++++++------ .../tests/types/test_context_mapping.py | 4 -- 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 97d605fc..432f3d78 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -75,7 +75,6 @@ class ModelVersion(BaseContext, Prefixable): description: Description of the object. external_id: Customizable ID. Has to be unique among instances of the same type. artifacts: Artifacts associated with this version. - tags: Tags associated with this version. metadata: Metadata associated with this version. """ @@ -83,7 +82,6 @@ class ModelVersion(BaseContext, Prefixable): version: str author: str artifacts: list[BaseArtifact] = field(init=False, factory=list) - tags: list[str] = field(init=False, factory=list) metadata: dict[str, ScalarType] = field(init=False, factory=dict) _registered_model_id: str | None = field(init=False, default=None) @@ -103,10 +101,11 @@ def mlmd_name_prefix(self) -> str: def map(self, type_id: int) -> Context: mlmd_obj = super().map(type_id) # this should match the name of the registered model - mlmd_obj.properties["model_name"].string_value = self.model_name - mlmd_obj.properties["author"].string_value = self.author - if self.tags: - mlmd_obj.properties["tags"].string_value = ",".join(self.tags) + props = { + "model_name": self.model_name, + "author": self.author, + } + self._map_props(props, mlmd_obj.properties) self._map_props(self.metadata, mlmd_obj.custom_properties) return mlmd_obj @@ -120,10 +119,6 @@ def unmap(cls, mlmd_obj: Context) -> ModelVersion: py_obj.version = py_obj.name py_obj.model_name = mlmd_obj.properties["model_name"].string_value py_obj.author = mlmd_obj.properties["author"].string_value - tags = mlmd_obj.properties["tags"].string_value - if tags: - tags = tags.split(",") - py_obj.tags = tags or [] py_obj.metadata = cls._unmap_props(mlmd_obj.custom_properties) return py_obj diff --git a/clients/python/tests/conftest.py b/clients/python/tests/conftest.py index faf3df4b..04e81fe4 100644 --- a/clients/python/tests/conftest.py +++ b/clients/python/tests/conftest.py @@ -18,11 +18,14 @@ ProtoTypeType = Union[ArtifactType, ContextType] + # ruff: noqa: PT021 supported @pytest.fixture(scope="session") def mlmd_conn(request) -> MetadataStoreClientConfig: model_registry_root_dir = model_registry_root(request) - print("Assuming this is the Model Registry root directory:", model_registry_root_dir) + print( + "Assuming this is the Model Registry root directory:", model_registry_root_dir + ) shared_volume = model_registry_root_dir / "test/config/ml-metadata" sqlite_db_file = shared_volume / "metadata.sqlite.db" if sqlite_db_file.exists(): @@ -30,15 +33,21 @@ def mlmd_conn(request) -> MetadataStoreClientConfig: raise FileExistsError(msg) container = DockerContainer("gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0") container.with_exposed_ports(8080) - container.with_volume_mapping(shared_volume, "/tmp/shared", "rw") # noqa this is file target in container - container.with_env("METADATA_STORE_SERVER_CONFIG_FILE", "/tmp/shared/conn_config.pb") # noqa this is target in container + container.with_volume_mapping( + shared_volume, + "/tmp/shared", # noqa: S108 + "rw", + ) + container.with_env( + "METADATA_STORE_SERVER_CONFIG_FILE", + "/tmp/shared/conn_config.pb", # noqa: S108 + ) container.start() wait_for_logs(container, "Server listening on") - os.system('docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a') # noqa governed test + os.system('docker container ls --format "table {{.ID}}\t{{.Names}}\t{{.Ports}}" -a') # noqa governed test print("waited for logs and port") cfg = MetadataStoreClientConfig( - host = "localhost", - port = int(container.get_exposed_port(8080)) + host="localhost", port=int(container.get_exposed_port(8080)) ) print(cfg) @@ -51,7 +60,9 @@ def teardown(): request.addfinalizer(teardown) - time.sleep(3) # allowing some time for mlmd grpc to fully stabilize (is "spent" once per pytest session anyway) + time.sleep( + 3 + ) # allowing some time for mlmd grpc to fully stabilize (is "spent" once per pytest session anyway) _throwaway_store = metadata_store.MetadataStore(cfg) wait_for_grpc(container, _throwaway_store) @@ -64,7 +75,10 @@ def model_registry_root(request): @pytest.fixture() def plain_wrapper(request, mlmd_conn: MetadataStoreClientConfig) -> MLMDStore: - sqlite_db_file = model_registry_root(request) / "test/config/ml-metadata/metadata.sqlite.db" + sqlite_db_file = ( + model_registry_root(request) / "test/config/ml-metadata/metadata.sqlite.db" + ) + def teardown(): try: os.remove(sqlite_db_file) @@ -110,7 +124,6 @@ def store_wrapper(plain_wrapper: MLMDStore) -> MLMDStore: "description", "model_name", "state", - "tags", ], ) @@ -137,7 +150,12 @@ def mr_api(store_wrapper: MLMDStore) -> ModelRegistryAPIClient: return mr -def wait_for_grpc(container: DockerContainer, store: metadata_store.MetadataStore, timeout=6, interval=2): +def wait_for_grpc( + container: DockerContainer, + store: metadata_store.MetadataStore, + timeout=6, + interval=2, +): start = time.time() while True: duration = time.time() - start @@ -151,6 +169,5 @@ def wait_for_grpc(container: DockerContainer, store: metadata_store.MetadataStor if results is not None: return duration if timeout and duration > timeout: - raise TimeoutError("wait_for_grpc not ready %.3f seconds" - % timeout) + raise TimeoutError("wait_for_grpc not ready %.3f seconds" % timeout) time.sleep(interval) diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index 50e95a8d..f14a43c7 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -20,7 +20,6 @@ def full_model_version() -> Mapped: proto_version.properties["description"].string_value = "test description" proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" - proto_version.properties["tags"].string_value = "test_tag1,test_tag2" proto_version.properties["state"].string_value = "ARCHIVED" proto_version.custom_properties["int_key"].int_value = 1 proto_version.custom_properties["float_key"].double_value = 1.0 @@ -35,7 +34,6 @@ def full_model_version() -> Mapped: description="test description", ) py_version._registered_model_id = "1" - py_version.tags = ["test_tag1", "test_tag2"] py_version.metadata = { "int_key": 1, "float_key": 1.0, @@ -75,7 +73,6 @@ def test_partial_model_version_unmapping(minimal_model_version: Mapped): assert unmapped_version.model_name == py_version.model_name assert unmapped_version.author == py_version.author assert unmapped_version.state == py_version.state - assert unmapped_version.tags == py_version.tags assert unmapped_version.metadata == py_version.metadata @@ -98,5 +95,4 @@ def test_full_model_version_unmapping(full_model_version: Mapped): assert unmapped_version.model_name == py_version.model_name assert unmapped_version.author == py_version.author assert unmapped_version.state == py_version.state - assert unmapped_version.tags == py_version.tags assert unmapped_version.metadata == py_version.metadata From 0d7e4a3861a4e6583117bd5ba80bbf4a2f346fc8 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 3 Jan 2024 19:21:00 -0300 Subject: [PATCH 210/254] py: base: simplify unmap Signed-off-by: Isabella Basso do Amaral --- .../python/src/model_registry/types/base.py | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/clients/python/src/model_registry/types/base.py b/clients/python/src/model_registry/types/base.py index d110b1d0..723813dc 100644 --- a/clients/python/src/model_registry/types/base.py +++ b/clients/python/src/model_registry/types/base.py @@ -4,7 +4,7 @@ from abc import ABC, abstractmethod from collections.abc import Mapping -from typing import Any, TypeVar +from typing import Any, TypeVar, get_args from attrs import define, field from typing_extensions import override @@ -160,19 +160,12 @@ def _unmap_props(mlmd_props: dict[str, Any]) -> dict[str, ScalarType]: Python properties. """ py_props: dict[str, ScalarType] = {} - for key, value in mlmd_props.items(): - # TODO: use pattern matching here (3.10) - if value.HasField("bool_value"): - py_props[key] = value.bool_value - elif value.HasField("int_value"): - py_props[key] = value.int_value - elif value.HasField("double_value"): - py_props[key] = value.double_value - elif value.HasField("string_value"): - py_props[key] = value.string_value - else: - msg = f"Unsupported type: {type(value)}" + for key, prop in mlmd_props.items(): + _, value = prop.ListFields()[0] + if not isinstance(value, get_args(ScalarType)): + msg = f"Unsupported type {type(value)} on key {key}" raise Exception(msg) + py_props[key] = value return py_props From 37f75912c8b774fea3ccb2eb468a232bf4a91a13 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 3 Jan 2024 19:21:00 -0300 Subject: [PATCH 211/254] py: wrapper: skip type check on _get_type_id Signed-off-by: Isabella Basso do Amaral --- .../src/model_registry/store/wrapper.py | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/clients/python/src/model_registry/store/wrapper.py b/clients/python/src/model_registry/store/wrapper.py index ff195d76..57c56dd7 100644 --- a/clients/python/src/model_registry/store/wrapper.py +++ b/clients/python/src/model_registry/store/wrapper.py @@ -20,7 +20,6 @@ ServerException, StoreException, TypeNotFoundException, - UnsupportedTypeException, ) from .base import ProtoType @@ -40,11 +39,11 @@ def __init__(self, config: MetadataStoreClientConfig): """ self._mlmd_store = MetadataStore(config) - def get_type_id(self, mlmd_pt: type[ProtoType], type_name: str) -> int: + def get_type_id(self, pt: type[ProtoType], type_name: str) -> int: """Get backend ID for a type. Args: - mlmd_pt: Proto type. + pt: Proto type. type_name: Name of the type. Returns: @@ -53,32 +52,22 @@ def get_type_id(self, mlmd_pt: type[ProtoType], type_name: str) -> int: Raises: TypeNotFoundException: If the type doesn't exist. ServerException: If there was an error getting the type. - UnsupportedTypeException: If the type is not supported. """ if type_name in self._type_ids: return self._type_ids[type_name] - if mlmd_pt is Artifact: - mlmd_pt_name = "artifact" - get_type = self._mlmd_store.get_artifact_type - elif mlmd_pt is Context: - mlmd_pt_name = "context" - get_type = self._mlmd_store.get_context_type - else: - msg = f"Unsupported type: {mlmd_pt}" - raise UnsupportedTypeException(msg) + pt_name = pt.__name__.lower() try: - _type = get_type(type_name) + _type = getattr(self._mlmd_store, f"get_{pt_name}_type")(type_name) except errors.NotFoundError as e: - msg = f"{mlmd_pt_name} type {type_name} does not exist" + msg = f"{pt_name} type {type_name} does not exist" raise TypeNotFoundException(msg) from e except errors.InternalError as e: - msg = f"Couldn't get {mlmd_pt_name} type {type_name} from MLMD store" + msg = f"Couldn't get {pt_name} type {type_name} from MLMD store" raise ServerException(msg) from e self._type_ids[type_name] = _type.id - return _type.id def put_artifact(self, artifact: Artifact) -> int: From fc3ccbcdc8390de2bee4f10db1d7b23e1095dc59 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 3 Jan 2024 19:21:00 -0300 Subject: [PATCH 212/254] py: client: add params for metadata input on register Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 26 ++++++++++++------- clients/python/src/model_registry/_client.py | 19 +++++++++++--- .../src/model_registry/types/contexts.py | 2 +- .../tests/types/test_context_mapping.py | 25 +++++++++--------- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index 1e1199ee..4600675e 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -12,15 +12,23 @@ from model_registry import ModelRegistry registry = ModelRegistry(server_address="server-address", port=9090, author="author") -model = registry.register_model("my-model", - "s3://path/to/model", - model_format_name="onnx", - model_format_version="1", - storage_key="aws-connection-path", - storage_path="to/model", - version="v2.0", - description="lorem ipsum", - ) +model = registry.register_model( + "my-model", # model name + "s3://path/to/model", # model URI + version="2.0.0", + description="lorem ipsum", + model_format_name="onnx", + model_format_version="1", + storage_key="aws-connection-path", + storage_path="path/to/model", + metadata={ + # can be one of the following types + "int_key": 1, + "bool_key": False, + "float_key": 3.14, + "str_key": "str_value", + } +) model = registry.get_registered_model("my-model") diff --git a/clients/python/src/model_registry/_client.py b/clients/python/src/model_registry/_client.py index 6b545b56..c084392c 100644 --- a/clients/python/src/model_registry/_client.py +++ b/clients/python/src/model_registry/_client.py @@ -3,6 +3,7 @@ from .core import ModelRegistryAPIClient from .exceptions import StoreException +from .store import ScalarType from .types import ModelArtifact, ModelVersion, RegisteredModel @@ -43,14 +44,14 @@ def _register_model(self, name: str) -> RegisteredModel: return rm def _register_new_version( - self, rm: RegisteredModel, version: str, /, description: str | None + self, rm: RegisteredModel, version: str, author: str, /, **kwargs ) -> ModelVersion: assert rm.id is not None, "Registered model must have an ID" if self._api.get_model_version_by_params(rm.id, version): msg = f"Version {version} already exists" raise StoreException(msg) - mv = ModelVersion(rm.name, version, self._author, description=description) + mv = ModelVersion(rm.name, version, author, **kwargs) self._api.upsert_model_version(mv, rm.id) return mv @@ -70,10 +71,12 @@ def register_model( model_format_name: str, model_format_version: str, version: str, + author: str | None = None, description: str | None = None, storage_key: str | None = None, storage_path: str | None = None, service_account_name: str | None = None, + metadata: dict[str, ScalarType] | None = None, ) -> RegisteredModel: """Register a model. @@ -84,19 +87,27 @@ def register_model( uri: URI of the model. Keyword Args: + version: Version of the model. Has to be unique. model_format_name: Name of the model format. model_format_version: Version of the model format. - version: Version of the model. Has to be unique. description: Description of the model. + author: Author of the model. Defaults to the client author. storage_key: Storage key. storage_path: Storage path. service_account_name: Service account name. + metadata: Additional version metadata. Returns: Registered model. """ rm = self._register_model(name) - mv = self._register_new_version(rm, version, description=description) + mv = self._register_new_version( + rm, + version, + author or self._author, + description=description, + metadata=metadata or {}, + ) self._register_model_artifact( mv, uri, diff --git a/clients/python/src/model_registry/types/contexts.py b/clients/python/src/model_registry/types/contexts.py index 432f3d78..5d7d964d 100644 --- a/clients/python/src/model_registry/types/contexts.py +++ b/clients/python/src/model_registry/types/contexts.py @@ -81,8 +81,8 @@ class ModelVersion(BaseContext, Prefixable): model_name: str version: str author: str + metadata: dict[str, ScalarType] = field(factory=dict) artifacts: list[BaseArtifact] = field(init=False, factory=list) - metadata: dict[str, ScalarType] = field(init=False, factory=dict) _registered_model_id: str | None = field(init=False, default=None) diff --git a/clients/python/tests/types/test_context_mapping.py b/clients/python/tests/types/test_context_mapping.py index f14a43c7..4ca24cff 100644 --- a/clients/python/tests/types/test_context_mapping.py +++ b/clients/python/tests/types/test_context_mapping.py @@ -13,10 +13,11 @@ @pytest.fixture() def full_model_version() -> Mapped: - proto_version = Context() - proto_version.name = "1:1.0.0" - proto_version.type_id = 2 - proto_version.external_id = "test_external_id" + proto_version = Context( + name="1:1.0.0", + type_id=2, + external_id="test_external_id", + ) proto_version.properties["description"].string_value = "test description" proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" @@ -32,23 +33,21 @@ def full_model_version() -> Mapped: "test_author", external_id="test_external_id", description="test description", + metadata={ + "int_key": 1, + "float_key": 1.0, + "bool_key": True, + "str_key": "test_str", + }, ) py_version._registered_model_id = "1" - py_version.metadata = { - "int_key": 1, - "float_key": 1.0, - "bool_key": True, - "str_key": "test_str", - } py_version.state = ContextState.ARCHIVED return Mapped(proto_version, py_version) @pytest.fixture() def minimal_model_version() -> Mapped: - proto_version = Context() - proto_version.name = "1:1.0.0" - proto_version.type_id = 2 + proto_version = Context(name="1:1.0.0", type_id=2) proto_version.properties["model_name"].string_value = "test_model" proto_version.properties["author"].string_value = "test_author" proto_version.properties["state"].string_value = "LIVE" From 0497cf4b325e509e8adabaf45f3fbf3864858d80 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 3 Jan 2024 19:21:01 -0300 Subject: [PATCH 213/254] py: add support for huggingface imports Signed-off-by: Isabella Basso do Amaral --- clients/python/README.md | 35 ++++++ clients/python/noxfile.py | 9 +- clients/python/poetry.lock | 108 ++++++++++++++++++- clients/python/pyproject.toml | 5 + clients/python/src/model_registry/_client.py | 95 ++++++++++++++++ clients/python/tests/test_client.py | 34 ++++++ 6 files changed, 284 insertions(+), 2 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index 4600675e..c78d55e3 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -37,6 +37,41 @@ version = registry.get_model_version("my-model", "v2.0") experiment = registry.get_model_artifact("my-model", "v2.0") ``` +### Importing from Hugging Face Hub + +To import models from Hugging Face Hub, start by installing the `huggingface-hub` package, either directly or as an +extra (available as `model-registry[hf]`). +Models can be imported with + +```py +hf_model = registry.register_hf_model( + "hf-namespace/hf-model", # HF repo + "relative/path/to/model/file.onnx", + version="1.2.3", + model_name="my-model", + description="lorem ipsum", + model_format_name="onnx", + model_format_version="1", +) +``` + +There are caveats to be noted when using this method: + +- It's only possible to import a single model file per Hugging Face Hub repo right now. +- If the model you want to import is in a global namespace, you should provide an author, e.g. + + ```py + hf_model = registry.register_hf_model( + "gpt2", # this model implicitly has no author + "onnx/decoder_model.onnx", + author="OpenAI", # Defaults to unknown in the absence of an author + version="1.0.0", + description="gpt-2 model", + model_format_name="onnx", + model_format_version="1", + ) + ``` + ## Development Common tasks, such as building documentation and running tests, can be executed using [`nox`](https://github.com/wntrblm/nox) sessions. diff --git a/clients/python/noxfile.py b/clients/python/noxfile.py index 7e35e75f..ad66ffd6 100644 --- a/clients/python/noxfile.py +++ b/clients/python/noxfile.py @@ -49,7 +49,14 @@ def mypy(session: Session) -> None: def tests(session: Session) -> None: """Run the test suite.""" session.install(".") - session.install("coverage[toml]", "pytest", "pytest-cov", "pygments", "testcontainers") + session.install( + "coverage[toml]", + "pytest", + "pytest-cov", + "pygments", + "testcontainers", + "huggingface-hub", + ) try: session.run( "pytest", diff --git a/clients/python/poetry.lock b/clients/python/poetry.lock index cd410389..e09d8338 100644 --- a/clients/python/poetry.lock +++ b/clients/python/poetry.lock @@ -319,6 +319,57 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "filelock" +version = "3.13.1" +description = "A platform independent file lock." +optional = true +python-versions = ">=3.8" +files = [ + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] + +[[package]] +name = "fsspec" +version = "2023.12.2" +description = "File-system specification" +optional = true +python-versions = ">=3.8" +files = [ + {file = "fsspec-2023.12.2-py3-none-any.whl", hash = "sha256:d800d87f72189a745fa3d6b033b9dc4a34ad069f60ca60b943a63599f5501960"}, + {file = "fsspec-2023.12.2.tar.gz", hash = "sha256:8548d39e8810b59c38014934f6b31e57f40c1b20f911f4cc2b85389c7e9bf0cb"}, +] + +[package.extras] +abfs = ["adlfs"] +adl = ["adlfs"] +arrow = ["pyarrow (>=1)"] +dask = ["dask", "distributed"] +devel = ["pytest", "pytest-cov"] +dropbox = ["dropbox", "dropboxdrivefs", "requests"] +full = ["adlfs", "aiohttp (!=4.0.0a0,!=4.0.0a1)", "dask", "distributed", "dropbox", "dropboxdrivefs", "fusepy", "gcsfs", "libarchive-c", "ocifs", "panel", "paramiko", "pyarrow (>=1)", "pygit2", "requests", "s3fs", "smbprotocol", "tqdm"] +fuse = ["fusepy"] +gcs = ["gcsfs"] +git = ["pygit2"] +github = ["requests"] +gs = ["gcsfs"] +gui = ["panel"] +hdfs = ["pyarrow (>=1)"] +http = ["aiohttp (!=4.0.0a0,!=4.0.0a1)", "requests"] +libarchive = ["libarchive-c"] +oci = ["ocifs"] +s3 = ["s3fs"] +sftp = ["paramiko"] +smb = ["smbprotocol"] +ssh = ["paramiko"] +tqdm = ["tqdm"] + [[package]] name = "furo" version = "2023.9.10" @@ -402,6 +453,38 @@ files = [ [package.extras] protobuf = ["grpcio-tools (>=1.59.3)"] +[[package]] +name = "huggingface-hub" +version = "0.20.1" +description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" +optional = true +python-versions = ">=3.8.0" +files = [ + {file = "huggingface_hub-0.20.1-py3-none-any.whl", hash = "sha256:ecfdea395a8bc68cd160106c5bd857f7e010768d95f9e1862a779010cc304831"}, + {file = "huggingface_hub-0.20.1.tar.gz", hash = "sha256:8c88c4c3c8853e22f2dfb4d84c3d493f4e1af52fb3856a90e1eeddcf191ddbb1"}, +] + +[package.dependencies] +filelock = "*" +fsspec = ">=2023.5.0" +packaging = ">=20.9" +pyyaml = ">=5.1" +requests = "*" +tqdm = ">=4.42.1" +typing-extensions = ">=3.7.4.3" + +[package.extras] +all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +cli = ["InquirerPy (==0.3.4)"] +dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "mypy (==1.5.1)", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.1.3)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] +inference = ["aiohttp", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)"] +quality = ["mypy (==1.5.1)", "ruff (>=0.1.3)"] +tensorflow = ["graphviz", "pydot", "tensorflow"] +testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "gradio", "jedi", "numpy", "pydantic (>1.1,<2.0)", "pydantic (>1.1,<3.0)", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] +torch = ["torch"] +typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] + [[package]] name = "idna" version = "3.6" @@ -1252,6 +1335,26 @@ files = [ {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, ] +[[package]] +name = "tqdm" +version = "4.66.1" +description = "Fast, Extensible Progress Meter" +optional = true +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.1-py3-none-any.whl", hash = "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386"}, + {file = "tqdm-4.66.1.tar.gz", hash = "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + [[package]] name = "typing-extensions" version = "4.8.0" @@ -1403,7 +1506,10 @@ files = [ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] +[extras] +hf = ["huggingface-hub"] + [metadata] lock-version = "2.0" python-versions = ">= 3.9, < 3.11" -content-hash = "0bec6ced2c16af94b1fc60510507065880d70bf1f3e786da393233ee345ed15c" +content-hash = "9a15e6a019ed38f48c6f58fa910b57d01492a59dd415423416ebf43084067d95" diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 3e9bcfc7..346b34fd 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -16,6 +16,11 @@ ml-metadata = "^1.14.0" # ml-metadata = { url = "https://github.com/tarilabs/ml-metadata-remote/releases/download/1.14.0/ml_metadata-1.14.0-py3-none-any.whl" } typing-extensions = "^4.8" +huggingface-hub = { version = "^0.20.1", optional = true } + +[tool.poetry.extras] +hf = ["huggingface-hub"] + [tool.poetry.group.dev.dependencies] sphinx = "^7.2.6" furo = "^2023.9.10" diff --git a/clients/python/src/model_registry/_client.py b/clients/python/src/model_registry/_client.py index c084392c..a4d5bafc 100644 --- a/clients/python/src/model_registry/_client.py +++ b/clients/python/src/model_registry/_client.py @@ -1,6 +1,9 @@ """Standard client for the model registry.""" from __future__ import annotations +from typing import get_args +from warnings import warn + from .core import ModelRegistryAPIClient from .exceptions import StoreException from .store import ScalarType @@ -120,6 +123,98 @@ def register_model( return rm + def register_hf_model( + self, + repo: str, + path: str, + *, + version: str, + model_format_name: str, + model_format_version: str, + author: str | None = None, + model_name: str | None = None, + description: str | None = None, + git_ref: str = "main", + ) -> RegisteredModel: + """Register a Hugging Face model. + + This imports a model from Hugging Face hub and registers it in the model registry. + Note that the model is not downloaded. + + Args: + repo: Name of the repository from Hugging Face hub. + path: URI of the model. + + Keyword Args: + version: Version of the model. Has to be unique. + model_format_name: Name of the model format. + model_format_version: Version of the model format. + author: Author of the model. Defaults to repo owner. + model_name: Name of the model. Defaults to the repo name. + description: Description of the model. + git_ref: Git reference to use. Defaults to `main`. + + Returns: + Registered model. + """ + try: + from huggingface_hub import HfApi, hf_hub_url, utils + except ImportError as e: + msg = "huggingface_hub is not installed" + raise StoreException(msg) from e + + api = HfApi() + try: + model_info = api.model_info(repo, revision=git_ref) + except utils.RepositoryNotFoundError as e: + msg = f"Repository {repo} does not exist" + raise StoreException(msg) from e + except utils.RevisionNotFoundError as e: + # TODO: as all hf-hub client calls default to using main, should we provide a tip? + msg = f"Revision {git_ref} does not exist" + raise StoreException(msg) from e + + if not author: + # model author can be None if the repo is in a "global" namespace (i.e. no / in repo). + if model_info.author is None: + model_author = "unknown" + warn( + "Model author is unknown. This is likely because the model is in a global namespace.", + stacklevel=2, + ) + else: + model_author = model_info.author + else: + model_author = author + source_uri = hf_hub_url(repo, path, revision=git_ref) + metadata = { + "repo": repo, + "source_uri": source_uri, + "model_origin": "huggingface_hub", + "model_author": model_author, + } + # card_data is the new field, but let's use the old one for backwards compatibility. + if card_data := model_info.cardData: + metadata.update( + { + k: v + for k, v in card_data.to_dict().items() + # TODO: (#151) preserve tags, possibly other complex metadata + if isinstance(v, get_args(ScalarType)) + } + ) + return self.register_model( + model_name or model_info.id, + source_uri, + author=author or model_author, + version=version, + model_format_name=model_format_name, + model_format_version=model_format_version, + description=description, + storage_path=path, + metadata=metadata, + ) + def get_registered_model(self, name: str) -> RegisteredModel | None: """Get a registered model. diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index dd6fa2d1..fe3c9e66 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -66,3 +66,37 @@ def test_get(mr_client: ModelRegistry): assert mv.id == _mv.id assert (_ma := mr_client.get_model_artifact(name, version)) assert ma.id == _ma.id + + +def test_hf_import(mr_client: ModelRegistry): + pytest.importorskip("huggingface_hub") + name = "gpt2" + version = "1.2.3" + + assert mr_client.register_hf_model( + name, + "onnx/decoder_model.onnx", + author="test author", + version=version, + model_format_name="test format", + model_format_version="test version", + ) + assert mr_client.get_model_version(name, version) + assert mr_client.get_model_artifact(name, version) + + +def test_hf_import_missing_author(mr_client: ModelRegistry): + pytest.importorskip("huggingface_hub") + name = "gpt2" + version = "1.2.3" + + with pytest.warns(match=r".*author is unknown.*"): + assert mr_client.register_hf_model( + name, + "onnx/decoder_model.onnx", + version=version, + model_format_name="test format", + model_format_version="test version", + ) + assert (mv := mr_client.get_model_version(name, version)) + assert mv.author == "unknown" From 225a2d78623adba452eae1924841155e4332077f Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Thu, 25 Jan 2024 12:27:33 +0100 Subject: [PATCH 214/254] fix Dockerfile NodeJS version for openapi-generator-cli (#273) --- Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Dockerfile b/Dockerfile index 243f81db..93f0143b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,10 @@ COPY ["go.mod", "go.sum", "./"] RUN go mod download USER root +# default NodeJS 14 is not enough for openapi-generator-cli, switch to Node JS currently supported +RUN yum remove -y nodejs npm +RUN yum module -y reset nodejs +RUN yum module -y enable nodejs:18 # install npm and java for openapi-generator-cli RUN yum install -y nodejs npm java-11 From 46d1f1cb1f98708c4c91cf4e06110250ef059162 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 12:34:07 +0100 Subject: [PATCH 215/254] build(deps): bump actions/setup-python from 4 to 5 (#270) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/run-robot-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-robot-tests.yaml b/.github/workflows/run-robot-tests.yaml index 03135217..ea824706 100644 --- a/.github/workflows/run-robot-tests.yaml +++ b/.github/workflows/run-robot-tests.yaml @@ -33,7 +33,7 @@ jobs: # Install defined Python version to run Robot Framework tests - name: Install Python 3.9.x # Get setup-python action to install Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: # Set Python version to install python-version: '3.9' From 655e4da403096fb9ef0426624130b281863aa505 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Fri, 26 Jan 2024 12:01:05 +0100 Subject: [PATCH 216/254] Decouple MLMD types setup from Go core library (#267) * implement Go core changes * add test coverage * refactoring * minor message change * nit: renamed function --- cmd/proxy.go | 5 + internal/apiutils/api_utils.go | 5 + internal/mlmdtypes/mlmdtypes.go | 144 ++++++++++++++++++++++++++ pkg/core/core.go | 172 ++++++++++---------------------- pkg/core/core_test.go | 61 ++++++----- 5 files changed, 243 insertions(+), 144 deletions(-) create mode 100644 internal/mlmdtypes/mlmdtypes.go diff --git a/cmd/proxy.go b/cmd/proxy.go index e9dea571..3bbc8adb 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -7,6 +7,7 @@ import ( "time" "github.com/golang/glog" + "github.com/opendatahub-io/model-registry/internal/mlmdtypes" "github.com/opendatahub-io/model-registry/internal/server/openapi" "github.com/opendatahub-io/model-registry/pkg/core" "github.com/spf13/cobra" @@ -48,6 +49,10 @@ func runProxyServer(cmd *cobra.Command, args []string) error { defer conn.Close() glog.Infof("connected to MLMD server") + _, err = mlmdtypes.CreateMLMDTypes(conn) + if err != nil { + return fmt.Errorf("error creating MLMD types: %v", err) + } service, err := core.NewModelRegistryService(conn) if err != nil { return fmt.Errorf("error creating core service: %v", err) diff --git a/internal/apiutils/api_utils.go b/internal/apiutils/api_utils.go index 8f5aaf49..ac28515c 100644 --- a/internal/apiutils/api_utils.go +++ b/internal/apiutils/api_utils.go @@ -46,6 +46,11 @@ func ZeroIfNil[T any](input *T) T { return *new(T) } +// of returns a pointer to the provided literal/const input +func Of[E any](e E) *E { + return &e +} + func BuildListOption(pageSize string, orderBy model.OrderByField, sortOrder model.SortOrder, nextPageToken string) (api.ListOptions, error) { var pageSizeInt32 *int32 if pageSize != "" { diff --git a/internal/mlmdtypes/mlmdtypes.go b/internal/mlmdtypes/mlmdtypes.go new file mode 100644 index 00000000..f8ab687d --- /dev/null +++ b/internal/mlmdtypes/mlmdtypes.go @@ -0,0 +1,144 @@ +package mlmdtypes + +import ( + "context" + "fmt" + + "github.com/opendatahub-io/model-registry/internal/apiutils" + "github.com/opendatahub-io/model-registry/internal/constants" + "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "google.golang.org/grpc" +) + +var ( + registeredModelTypeName = apiutils.Of(constants.RegisteredModelTypeName) + modelVersionTypeName = apiutils.Of(constants.ModelVersionTypeName) + modelArtifactTypeName = apiutils.Of(constants.ModelArtifactTypeName) + servingEnvironmentTypeName = apiutils.Of(constants.ServingEnvironmentTypeName) + inferenceServiceTypeName = apiutils.Of(constants.InferenceServiceTypeName) + serveModelTypeName = apiutils.Of(constants.ServeModelTypeName) + canAddFields = apiutils.Of(true) +) + +// Utility method that created the necessary Model Registry's logical-model types +// as the necessary MLMD's Context, Artifact, Execution types etc. in the underlying MLMD service +func CreateMLMDTypes(cc grpc.ClientConnInterface) (map[string]int64, error) { + client := proto.NewMetadataStoreServiceClient(cc) + + registeredModelReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: registeredModelTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + "state": proto.PropertyType_STRING, + }, + }, + } + + modelVersionReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: modelVersionTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + "model_name": proto.PropertyType_STRING, + "version": proto.PropertyType_STRING, + "author": proto.PropertyType_STRING, + "state": proto.PropertyType_STRING, + }, + }, + } + + modelArtifactReq := proto.PutArtifactTypeRequest{ + CanAddFields: canAddFields, + ArtifactType: &proto.ArtifactType{ + Name: modelArtifactTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + "model_format_name": proto.PropertyType_STRING, + "model_format_version": proto.PropertyType_STRING, + "storage_key": proto.PropertyType_STRING, + "storage_path": proto.PropertyType_STRING, + "service_account_name": proto.PropertyType_STRING, + }, + }, + } + + servingEnvironmentReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: servingEnvironmentTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + }, + }, + } + + inferenceServiceReq := proto.PutContextTypeRequest{ + CanAddFields: canAddFields, + ContextType: &proto.ContextType{ + Name: inferenceServiceTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + "model_version_id": proto.PropertyType_INT, + "registered_model_id": proto.PropertyType_INT, + // same information tracked using ParentContext association + "serving_environment_id": proto.PropertyType_INT, + "runtime": proto.PropertyType_STRING, + "desired_state": proto.PropertyType_STRING, + }, + }, + } + + serveModelReq := proto.PutExecutionTypeRequest{ + CanAddFields: canAddFields, + ExecutionType: &proto.ExecutionType{ + Name: serveModelTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + "model_version_id": proto.PropertyType_INT, + }, + }, + } + + registeredModelResp, err := client.PutContextType(context.Background(), ®isteredModelReq) + if err != nil { + return nil, fmt.Errorf("error setting up context type %s: %v", *registeredModelTypeName, err) + } + + modelVersionResp, err := client.PutContextType(context.Background(), &modelVersionReq) + if err != nil { + return nil, fmt.Errorf("error setting up context type %s: %v", *modelVersionTypeName, err) + } + + modelArtifactResp, err := client.PutArtifactType(context.Background(), &modelArtifactReq) + if err != nil { + return nil, fmt.Errorf("error setting up artifact type %s: %v", *modelArtifactTypeName, err) + } + + servingEnvironmentResp, err := client.PutContextType(context.Background(), &servingEnvironmentReq) + if err != nil { + return nil, fmt.Errorf("error setting up context type %s: %v", *servingEnvironmentTypeName, err) + } + + inferenceServiceResp, err := client.PutContextType(context.Background(), &inferenceServiceReq) + if err != nil { + return nil, fmt.Errorf("error setting up context type %s: %v", *inferenceServiceTypeName, err) + } + + serveModelResp, err := client.PutExecutionType(context.Background(), &serveModelReq) + if err != nil { + return nil, fmt.Errorf("error setting up execution type %s: %v", *serveModelTypeName, err) + } + + typesMap := map[string]int64{ + constants.RegisteredModelTypeName: registeredModelResp.GetTypeId(), + constants.ModelVersionTypeName: modelVersionResp.GetTypeId(), + constants.ModelArtifactTypeName: modelArtifactResp.GetTypeId(), + constants.ServingEnvironmentTypeName: servingEnvironmentResp.GetTypeId(), + constants.InferenceServiceTypeName: inferenceServiceResp.GetTypeId(), + constants.ServeModelTypeName: serveModelResp.GetTypeId(), + } + return typesMap, nil +} diff --git a/pkg/core/core.go b/pkg/core/core.go index cf53d851..e04a5dd5 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -18,13 +18,12 @@ import ( ) var ( - registeredModelTypeName = of(constants.RegisteredModelTypeName) - modelVersionTypeName = of(constants.ModelVersionTypeName) - modelArtifactTypeName = of(constants.ModelArtifactTypeName) - servingEnvironmentTypeName = of(constants.ServingEnvironmentTypeName) - inferenceServiceTypeName = of(constants.InferenceServiceTypeName) - serveModelTypeName = of(constants.ServeModelTypeName) - canAddFields = of(true) + registeredModelTypeName = apiutils.Of(constants.RegisteredModelTypeName) + modelVersionTypeName = apiutils.Of(constants.ModelVersionTypeName) + modelArtifactTypeName = apiutils.Of(constants.ModelArtifactTypeName) + servingEnvironmentTypeName = apiutils.Of(constants.ServingEnvironmentTypeName) + inferenceServiceTypeName = apiutils.Of(constants.InferenceServiceTypeName) + serveModelTypeName = apiutils.Of(constants.ServeModelTypeName) ) // ModelRegistryService is the core library of the model registry @@ -36,137 +35,81 @@ type ModelRegistryService struct { } // NewModelRegistryService creates a new instance of the ModelRegistryService, initializing it with the provided gRPC client connection. -// It sets up the necessary context and artifact types in the MLMD service. +// It _assumes_ the necessary MLMD's Context, Artifact, Execution types etc. are already setup in the underlying MLMD service. // // Parameters: // - cc: A gRPC client connection to the underlying MLMD service func NewModelRegistryService(cc grpc.ClientConnInterface) (api.ModelRegistryApi, error) { + typesMap, err := BuildTypesMap(cc) + if err != nil { // early return in case type Ids cannot be retrieved + return nil, err + } client := proto.NewMetadataStoreServiceClient(cc) - // Setup the needed Type instances if not existing already + return &ModelRegistryService{ + mlmdClient: client, + typesMap: typesMap, + openapiConv: &generated.OpenAPIConverterImpl{}, + mapper: mapper.NewMapper(typesMap), + }, nil +} - registeredModelReq := proto.PutContextTypeRequest{ - CanAddFields: canAddFields, - ContextType: &proto.ContextType{ - Name: registeredModelTypeName, - Properties: map[string]proto.PropertyType{ - "description": proto.PropertyType_STRING, - "state": proto.PropertyType_STRING, - }, - }, - } +func BuildTypesMap(cc grpc.ClientConnInterface) (map[string]int64, error) { + client := proto.NewMetadataStoreServiceClient(cc) - modelVersionReq := proto.PutContextTypeRequest{ - CanAddFields: canAddFields, - ContextType: &proto.ContextType{ - Name: modelVersionTypeName, - Properties: map[string]proto.PropertyType{ - "description": proto.PropertyType_STRING, - "model_name": proto.PropertyType_STRING, - "version": proto.PropertyType_STRING, - "author": proto.PropertyType_STRING, - "state": proto.PropertyType_STRING, - }, - }, + registeredModelContextTypeReq := proto.GetContextTypeRequest{ + TypeName: registeredModelTypeName, } - - modelArtifactReq := proto.PutArtifactTypeRequest{ - CanAddFields: canAddFields, - ArtifactType: &proto.ArtifactType{ - Name: modelArtifactTypeName, - Properties: map[string]proto.PropertyType{ - "description": proto.PropertyType_STRING, - "model_format_name": proto.PropertyType_STRING, - "model_format_version": proto.PropertyType_STRING, - "storage_key": proto.PropertyType_STRING, - "storage_path": proto.PropertyType_STRING, - "service_account_name": proto.PropertyType_STRING, - }, - }, + registeredModelResp, err := client.GetContextType(context.Background(), ®isteredModelContextTypeReq) + if err != nil { + return nil, fmt.Errorf("error getting context type %s: %v", *registeredModelTypeName, err) } - - servingEnvironmentReq := proto.PutContextTypeRequest{ - CanAddFields: canAddFields, - ContextType: &proto.ContextType{ - Name: servingEnvironmentTypeName, - Properties: map[string]proto.PropertyType{ - "description": proto.PropertyType_STRING, - }, - }, + modelVersionContextTypeReq := proto.GetContextTypeRequest{ + TypeName: modelVersionTypeName, } - - inferenceServiceReq := proto.PutContextTypeRequest{ - CanAddFields: canAddFields, - ContextType: &proto.ContextType{ - Name: inferenceServiceTypeName, - Properties: map[string]proto.PropertyType{ - "description": proto.PropertyType_STRING, - "model_version_id": proto.PropertyType_INT, - "registered_model_id": proto.PropertyType_INT, - // same information tracked using ParentContext association - "serving_environment_id": proto.PropertyType_INT, - "runtime": proto.PropertyType_STRING, - "desired_state": proto.PropertyType_STRING, - }, - }, + modelVersionResp, err := client.GetContextType(context.Background(), &modelVersionContextTypeReq) + if err != nil { + return nil, fmt.Errorf("error getting context type %s: %v", *modelVersionTypeName, err) } - - serveModelReq := proto.PutExecutionTypeRequest{ - CanAddFields: canAddFields, - ExecutionType: &proto.ExecutionType{ - Name: serveModelTypeName, - Properties: map[string]proto.PropertyType{ - "description": proto.PropertyType_STRING, - "model_version_id": proto.PropertyType_INT, - }, - }, + modelArtifactArtifactTypeReq := proto.GetArtifactTypeRequest{ + TypeName: modelArtifactTypeName, } - - registeredModelResp, err := client.PutContextType(context.Background(), ®isteredModelReq) + modelArtifactResp, err := client.GetArtifactType(context.Background(), &modelArtifactArtifactTypeReq) if err != nil { - return nil, fmt.Errorf("error setting up context type %s: %v", *registeredModelTypeName, err) + return nil, fmt.Errorf("error getting artifact type %s: %v", *modelArtifactTypeName, err) } - - modelVersionResp, err := client.PutContextType(context.Background(), &modelVersionReq) - if err != nil { - return nil, fmt.Errorf("error setting up context type %s: %v", *modelVersionTypeName, err) + servingEnvironmentContextTypeReq := proto.GetContextTypeRequest{ + TypeName: servingEnvironmentTypeName, } - - modelArtifactResp, err := client.PutArtifactType(context.Background(), &modelArtifactReq) + servingEnvironmentResp, err := client.GetContextType(context.Background(), &servingEnvironmentContextTypeReq) if err != nil { - return nil, fmt.Errorf("error setting up artifact type %s: %v", *modelArtifactTypeName, err) + return nil, fmt.Errorf("error getting context type %s: %v", *servingEnvironmentTypeName, err) } - - servingEnvironmentResp, err := client.PutContextType(context.Background(), &servingEnvironmentReq) - if err != nil { - return nil, fmt.Errorf("error setting up context type %s: %v", *servingEnvironmentTypeName, err) + inferenceServiceContextTypeReq := proto.GetContextTypeRequest{ + TypeName: inferenceServiceTypeName, } - - inferenceServiceResp, err := client.PutContextType(context.Background(), &inferenceServiceReq) + inferenceServiceResp, err := client.GetContextType(context.Background(), &inferenceServiceContextTypeReq) if err != nil { - return nil, fmt.Errorf("error setting up context type %s: %v", *inferenceServiceTypeName, err) + return nil, fmt.Errorf("error getting context type %s: %v", *inferenceServiceTypeName, err) } - - serveModelResp, err := client.PutExecutionType(context.Background(), &serveModelReq) + serveModelExecutionReq := proto.GetExecutionTypeRequest{ + TypeName: serveModelTypeName, + } + serveModelResp, err := client.GetExecutionType(context.Background(), &serveModelExecutionReq) if err != nil { - return nil, fmt.Errorf("error setting up execution type %s: %v", *serveModelTypeName, err) + return nil, fmt.Errorf("error getting execution type %s: %v", *serveModelTypeName, err) } typesMap := map[string]int64{ - constants.RegisteredModelTypeName: registeredModelResp.GetTypeId(), - constants.ModelVersionTypeName: modelVersionResp.GetTypeId(), - constants.ModelArtifactTypeName: modelArtifactResp.GetTypeId(), - constants.ServingEnvironmentTypeName: servingEnvironmentResp.GetTypeId(), - constants.InferenceServiceTypeName: inferenceServiceResp.GetTypeId(), - constants.ServeModelTypeName: serveModelResp.GetTypeId(), - } - return &ModelRegistryService{ - mlmdClient: client, - typesMap: typesMap, - openapiConv: &generated.OpenAPIConverterImpl{}, - mapper: mapper.NewMapper(typesMap), - }, nil + constants.RegisteredModelTypeName: registeredModelResp.ContextType.GetId(), + constants.ModelVersionTypeName: modelVersionResp.ContextType.GetId(), + constants.ModelArtifactTypeName: modelArtifactResp.ArtifactType.GetId(), + constants.ServingEnvironmentTypeName: servingEnvironmentResp.ContextType.GetId(), + constants.InferenceServiceTypeName: inferenceServiceResp.ContextType.GetId(), + constants.ServeModelTypeName: serveModelResp.ExecutionType.GetId(), + } + return typesMap, nil } // REGISTERED MODELS @@ -1420,8 +1363,3 @@ func (serv *ModelRegistryService) GetServeModels(listOptions api.ListOptions, in } return &toReturn, nil } - -// of returns a pointer to the provided literal/const input -func of[E any](e E) *E { - return &e -} diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index 3ce08194..e4473253 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -5,8 +5,10 @@ import ( "fmt" "testing" + "github.com/opendatahub-io/model-registry/internal/apiutils" "github.com/opendatahub-io/model-registry/internal/converter" "github.com/opendatahub-io/model-registry/internal/ml_metadata/proto" + "github.com/opendatahub-io/model-registry/internal/mlmdtypes" "github.com/opendatahub-io/model-registry/internal/testutils" "github.com/opendatahub-io/model-registry/pkg/api" "github.com/opendatahub-io/model-registry/pkg/openapi" @@ -51,6 +53,10 @@ type CoreTestSuite struct { mlmdClient proto.MetadataStoreServiceClient } +var ( + canAddFields = apiutils.Of(true) +) + func TestRunCoreTestSuite(t *testing.T) { // before all grpcConn, mlmdClient, teardown := testutils.SetupMLMetadataTestContainer(t) @@ -98,6 +104,8 @@ func (suite *CoreTestSuite) AfterTest(suiteName, testName string) { } func (suite *CoreTestSuite) setupModelRegistryService() *ModelRegistryService { + _, err := mlmdtypes.CreateMLMDTypes(suite.grpcConn) + suite.Nilf(err, "error creating MLMD types: %v", err) // setup model registry service service, err := NewModelRegistryService(suite.grpcConn) suite.Nilf(err, "error creating core service: %v", err) @@ -315,8 +323,7 @@ func (suite *CoreTestSuite) TestModelRegistryStartupWithExistingEmptyTypes() { suite.Equal(0, len(serveModelResp.ExecutionType.Properties)) // create model registry service - _, err = NewModelRegistryService(suite.grpcConn) - suite.Nil(err) + _ = suite.setupModelRegistryService() // assure the types have been correctly setup at startup // check NOT empty props @@ -420,8 +427,8 @@ func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInRegisteredM _, err := suite.mlmdClient.PutContextType(context.Background(), ®isteredModelReq) suite.Nil(err) - // create model registry service - _, err = NewModelRegistryService(suite.grpcConn) + // steps to create model registry service + _, err = mlmdtypes.CreateMLMDTypes(suite.grpcConn) suite.NotNil(err) suite.Regexp("error setting up context type odh.RegisteredModel: rpc error: code = AlreadyExists.*", err.Error()) } @@ -440,8 +447,8 @@ func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInModelVersio _, err := suite.mlmdClient.PutContextType(context.Background(), &modelVersionReq) suite.Nil(err) - // create model registry service - _, err = NewModelRegistryService(suite.grpcConn) + // steps to create model registry service + _, err = mlmdtypes.CreateMLMDTypes(suite.grpcConn) suite.NotNil(err) suite.Regexp("error setting up context type odh.ModelVersion: rpc error: code = AlreadyExists.*", err.Error()) } @@ -460,8 +467,8 @@ func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInModelArtifa _, err := suite.mlmdClient.PutArtifactType(context.Background(), &modelArtifactReq) suite.Nil(err) - // create model registry service - _, err = NewModelRegistryService(suite.grpcConn) + // steps to create model registry service + _, err = mlmdtypes.CreateMLMDTypes(suite.grpcConn) suite.NotNil(err) suite.Regexp("error setting up artifact type odh.ModelArtifact: rpc error: code = AlreadyExists.*", err.Error()) } @@ -479,8 +486,8 @@ func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInServingEnvi _, err := suite.mlmdClient.PutContextType(context.Background(), &servingEnvironmentReq) suite.Nil(err) - // create model registry service - _, err = NewModelRegistryService(suite.grpcConn) + // steps to create model registry service + _, err = mlmdtypes.CreateMLMDTypes(suite.grpcConn) suite.NotNil(err) suite.Regexp("error setting up context type odh.ServingEnvironment: rpc error: code = AlreadyExists.*", err.Error()) } @@ -499,8 +506,8 @@ func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInInferenceSe _, err := suite.mlmdClient.PutContextType(context.Background(), &inferenceServiceReq) suite.Nil(err) - // create model registry service - _, err = NewModelRegistryService(suite.grpcConn) + // steps to create model registry service + _, err = mlmdtypes.CreateMLMDTypes(suite.grpcConn) suite.NotNil(err) suite.Regexp("error setting up context type odh.InferenceService: rpc error: code = AlreadyExists.*", err.Error()) } @@ -519,8 +526,8 @@ func (suite *CoreTestSuite) TestModelRegistryFailureForOmittedFieldInServeModel( _, err := suite.mlmdClient.PutExecutionType(context.Background(), &serveModelReq) suite.Nil(err) - // create model registry service - _, err = NewModelRegistryService(suite.grpcConn) + // steps to create model registry service + _, err = mlmdtypes.CreateMLMDTypes(suite.grpcConn) suite.NotNil(err) suite.Regexp("error setting up execution type odh.ServeModel: rpc error: code = AlreadyExists.*", err.Error()) } @@ -700,7 +707,7 @@ func (suite *CoreTestSuite) TestGetRegisteredModelByParamsWithNoResults() { // create mode registry service service := suite.setupModelRegistryService() - _, err := service.GetRegisteredModelByParams(of("not-present"), nil) + _, err := service.GetRegisteredModelByParams(apiutils.Of("not-present"), nil) suite.NotNil(err) suite.Equal("no registered models found for name=not-present, externalId=", err.Error()) } @@ -1145,7 +1152,7 @@ func (suite *CoreTestSuite) TestGetModelVersionByParamsWithNoResults() { registeredModelId := suite.registerModel(service, nil, nil) - _, err := service.GetModelVersionByParams(of("not-present"), ®isteredModelId, nil) + _, err := service.GetModelVersionByParams(apiutils.Of("not-present"), ®isteredModelId, nil) suite.NotNil(err) suite.Equal("no model versions found for versionName=not-present, registeredModelId=1, externalId=", err.Error()) } @@ -1351,10 +1358,10 @@ func (suite *CoreTestSuite) TestCreateModelArtifact() { State: (*openapi.ArtifactState)(&artifactState), Uri: &artifactUri, Description: &artifactDescription, - ModelFormatName: of("onnx"), - ModelFormatVersion: of("1"), - StorageKey: of("aws-connection-models"), - StoragePath: of("bucket"), + ModelFormatName: apiutils.Of("onnx"), + ModelFormatVersion: apiutils.Of("1"), + StorageKey: apiutils.Of("aws-connection-models"), + StoragePath: apiutils.Of("bucket"), CustomProperties: &map[string]openapi.MetadataValue{ "custom_string_prop": { MetadataStringValue: &openapi.MetadataStringValue{ @@ -1633,7 +1640,7 @@ func (suite *CoreTestSuite) TestGetModelArtifactByParamsWithNoResults() { modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) - _, err := service.GetModelArtifactByParams(of("not-present"), &modelVersionId, nil) + _, err := service.GetModelArtifactByParams(apiutils.Of("not-present"), &modelVersionId, nil) suite.NotNil(err) suite.Equal("no model artifacts found for artifactName=not-present, modelVersionId=2, externalId=", err.Error()) } @@ -1893,7 +1900,7 @@ func (suite *CoreTestSuite) TestGetServingEnvironmentByParamsWithNoResults() { // create mode registry service service := suite.setupModelRegistryService() - _, err := service.GetServingEnvironmentByParams(of("not-present"), nil) + _, err := service.GetServingEnvironmentByParams(apiutils.Of("not-present"), nil) suite.NotNil(err) suite.Equal("no serving environments found for name=not-present, externalId=", err.Error()) } @@ -2533,7 +2540,7 @@ func (suite *CoreTestSuite) TestGetInferenceServiceByParamsWithNoResults() { parentResourceId := suite.registerServingEnvironment(service, nil, nil) - _, err := service.GetInferenceServiceByParams(of("not-present"), &parentResourceId, nil) + _, err := service.GetInferenceServiceByParams(apiutils.Of("not-present"), &parentResourceId, nil) suite.NotNil(err) suite.Equal("no inference services found for name=not-present, servingEnvironmentId=1, externalId=", err.Error()) } @@ -2672,7 +2679,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &entityExternalId2, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, - Runtime: of("model-server0"), + Runtime: apiutils.Of("model-server0"), } secondName := "v2" @@ -2682,7 +2689,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &secondExtId, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, - Runtime: of("model-server1"), + Runtime: apiutils.Of("model-server1"), } thirdName := "v3" @@ -2692,7 +2699,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &thirdExtId, ServingEnvironmentId: parentResourceId, RegisteredModelId: registeredModelId, - Runtime: of("model-server2"), + Runtime: apiutils.Of("model-server2"), } createdEntity1, err := service.UpsertInferenceService(eut1) @@ -2715,7 +2722,7 @@ func (suite *CoreTestSuite) TestGetInferenceServices() { ExternalID: &anotherExtId, ServingEnvironmentId: anotherParentResourceId, RegisteredModelId: registeredModelId, - Runtime: of("model-server3"), + Runtime: apiutils.Of("model-server3"), } _, err = service.UpsertInferenceService(eutAnother) From ff9abb5c922e96bbcc2a94548d1b0932fe8cab86 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 26 Jan 2024 08:01:08 -0800 Subject: [PATCH 217/254] chore: Add kind integration test, fixes #251 (#252) * chore: Add kind integration test, fixes #251 * Remove unused IMG_VERSION env variable in pr build workflow --- .github/workflows/build-image-pr.yml | 33 ++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index 8fe7f01b..d4a18ad9 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -1,4 +1,4 @@ -name: Test container image build +name: Test container image build and deployment on: pull_request: @@ -15,9 +15,10 @@ on: env: QUAY_IMG_REPO: model-registry PUSH_IMAGE: false + BRANCH: ${{ github.base_ref }} jobs: - build-image: + build-and-test-image: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -33,3 +34,31 @@ jobs: env: VERSION: ${{ steps.tags.outputs.tag }} run: ./scripts/build_deploy.sh + - name: Start Kind Cluster + uses: helm/kind-action@v1.4.0 + - name: Load Local Registry Test Image + env: + IMG: "quay.io/opendatahub/model-registry:${{ steps.tags.outputs.tag }}" + run: | + kind load docker-image -n chart-testing ${IMG} + - name: Deploy Operator With Test Image + env: + IMG: "quay.io/opendatahub/model-registry:${{ steps.tags.outputs.tag }}" + run: | + echo "Deploying operator from model-registry-operator branch ${BRANCH}" + kubectl apply -k "https://github.com/opendatahub-io/model-registry-operator.git/config/default?ref=${BRANCH}" + kubectl set env -n model-registry-operator-system deployment/model-registry-operator-controller-manager REST_IMAGE="${IMG}" + - name: Create Test Registry + run: | + kubectl apply -k "https://github.com/opendatahub-io/model-registry-operator.git/config/samples?ref=${BRANCH}" + kubectl get mr + - name: Wait for Test Registry Deployment + timeout-minutes: 5 + run: | + CONDITION="false" + while [ "${CONDITION}" != "True" ] + do + sleep 5 + CONDITION="`kubectl get mr modelregistry-sample --output=jsonpath='{.status.conditions[?(@.type=="Available")].status}'`" + echo "Registry Available=${CONDITION}" + done From 9787f7c1f51395e5d1a3a636321507022dafd0c5 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Fri, 26 Jan 2024 17:10:42 +0100 Subject: [PATCH 218/254] Added Dockerfile without generation phase (#274) --- Dockerfile.odh | 34 ++++++++++++++++++++++++++++++++++ Makefile | 10 +++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 Dockerfile.odh diff --git a/Dockerfile.odh b/Dockerfile.odh new file mode 100644 index 00000000..86e2114b --- /dev/null +++ b/Dockerfile.odh @@ -0,0 +1,34 @@ +# Build the model-registry binary +FROM registry.access.redhat.com/ubi8/go-toolset:1.19 as builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY ["go.mod", "go.sum", "./"] +# cache deps before building and copying source so that we don't need to re-download as much +# and so that source changes don't invalidate our downloaded layer +RUN go mod download + +USER root + +# Copy the go source +COPY ["Makefile", "main.go", ".openapi-generator-ignore", "openapitools.json", "./"] + +# Copy rest of the source +COPY bin/ bin/ +COPY cmd/ cmd/ +COPY api/ api/ +COPY internal/ internal/ +COPY pkg/ pkg/ + +# Build +RUN CGO_ENABLED=1 GOOS=linux GOARCH=amd64 make clean/odh build/odh + +# Use distroless as minimal base image to package the model-registry binary +# Refer to https://github.com/GoogleContainerTools/distroless for more details +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.8 +WORKDIR / +# copy the registry binary +COPY --from=builder /workspace/model-registry . +USER 65532:65532 + +ENTRYPOINT ["/model-registry"] diff --git a/Makefile b/Makefile index 9024695e..a64f5e6e 100644 --- a/Makefile +++ b/Makefile @@ -99,6 +99,10 @@ vet: clean: rm -Rf ./model-registry internal/ml_metadata/proto/*.go internal/converter/generated/*.go pkg/openapi +.PHONY: clean/odh +clean/odh: + rm -Rf ./model-registry + bin/go-enum: GOBIN=$(PROJECT_BIN) go install github.com/searKing/golang/tools/go-enum@v1.2.97 @@ -147,12 +151,16 @@ vendor: build: gen vet lint go build +.PHONY: build/odh +build/odh: vet lint + go build + .PHONY: gen gen: deps gen/grpc gen/openapi gen/converter go generate ./... .PHONY: lint -lint: gen +lint: golangci-lint run main.go golangci-lint run cmd/... internal/... ./pkg/... From 6456367c4562193364fdd7ae55b8b8e37b6a9d7e Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Fri, 26 Jan 2024 19:20:46 -0800 Subject: [PATCH 219/254] fix: update image build and push to handle tags, fixes RHOAIENG-2300 (#276) * chore: rename directory doc to docs * fix: update image build and push to handle tags, fixes RHOAIENG-2300 * fix: fix links to docs --- .github/workflows/build-and-push-image.yml | 71 ++++++++++++++++++ .github/workflows/build-image-main.yml | 53 ------------- CONTRIBUTING.md | 4 +- README.md | 4 +- .../Model Registry Testing areas.drawio | 0 .../Model Registry Testing areas.png | Bin .../Screenshot 2023-11-29 at 14.08.12.png | Bin .../Screenshot 2023-11-29 at 14.10.14.png | Bin {doc => docs}/mr_go_library.md | 0 ...emote_only_packaging_of_MLMD_Python_lib.md | 0 10 files changed, 75 insertions(+), 57 deletions(-) create mode 100644 .github/workflows/build-and-push-image.yml delete mode 100644 .github/workflows/build-image-main.yml rename {doc => docs}/Model Registry Testing areas.drawio (100%) rename {doc => docs}/Model Registry Testing areas.png (100%) rename {doc => docs}/Screenshot 2023-11-29 at 14.08.12.png (100%) rename {doc => docs}/Screenshot 2023-11-29 at 14.10.14.png (100%) rename {doc => docs}/mr_go_library.md (100%) rename {doc => docs}/remote_only_packaging_of_MLMD_Python_lib.md (100%) diff --git a/.github/workflows/build-and-push-image.yml b/.github/workflows/build-and-push-image.yml new file mode 100644 index 00000000..0648b3e8 --- /dev/null +++ b/.github/workflows/build-and-push-image.yml @@ -0,0 +1,71 @@ +name: Container image build and tag + +on: + push: + branches: + - 'main' + tags: + - 'v*' + paths-ignore: + - 'LICENSE*' + - '**.gitignore' + - '**.md' + - '**.txt' + - '.github/ISSUE_TEMPLATE/**' + - '.github/dependabot.yml' + - 'docs/**' + +env: + QUAY_ORG: opendatahub + QUAY_IMG_REPO: model-registry + QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} + QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }} + PUSH_IMAGE: true + +jobs: + build-image: + runs-on: ubuntu-latest + steps: + # Assign context variable for various action contexts (tag, main, CI) + - name: Assigning tag context + if: github.head_ref == '' && startsWith(github.ref, 'refs/tags/v') + run: echo "BUILD_CONTEXT=tag" >> $GITHUB_ENV + - name: Assigning main context + if: github.head_ref == '' && github.ref == 'refs/heads/main' + run: echo "BUILD_CONTEXT=main" >> $GITHUB_ENV + # checkout branch + - uses: actions/checkout@v4 + # set image version + - name: Set main-branch environment + if: env.BUILD_CONTEXT == 'main' + run: | + commit_sha=${{ github.event.after }} + tag=main-${commit_sha:0:7} + echo "VERSION=${tag}" >> $GITHUB_ENV + - name: Set tag environment + if: env.BUILD_CONTEXT == 'tag' + run: | + echo "VERSION=${{ github.ref_name }}" >> $GITHUB_ENV + - name: Build and Push Image + shell: bash + run: ./scripts/build_deploy.sh + - name: Tag Latest + if: env.BUILD_CONTEXT == 'main' + shell: bash + env: + IMG: quay.io/${{ env.QUAY_ORG }}/${{ env.QUAY_IMG_REPO }} + BUILD_IMAGE: false + run: | + docker tag ${{ env.IMG }}:$VERSION ${{ env.IMG }}:latest + # BUILD_IMAGE=false skip the build + ./scripts/build_deploy.sh + - name: Tag Main + if: env.BUILD_CONTEXT == 'main' + shell: bash + env: + IMG: quay.io/${{ env.QUAY_ORG }}/${{ env.QUAY_IMG_REPO }} + BUILD_IMAGE: false + run: | + docker tag ${{ env.IMG }}:$VERSION ${{ env.IMG }}:main + # BUILD_IMAGE=false skip the build + ./scripts/build_deploy.sh diff --git a/.github/workflows/build-image-main.yml b/.github/workflows/build-image-main.yml deleted file mode 100644 index dcf44369..00000000 --- a/.github/workflows/build-image-main.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Main container image build and tag - -on: - push: - branches: - - 'main' - -env: - QUAY_ORG: opendatahub - QUAY_IMG_REPO: model-registry - QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} - QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }} - PUSH_IMAGE: true - -jobs: - build-image: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Generate Tag - shell: bash - id: tags - run: | - commit_sha=${{ github.event.after }} - tag=main-${commit_sha:0:7} - echo "tag=${tag}" >> $GITHUB_OUTPUT - - name: Build and Push Image - shell: bash - env: - VERSION: ${{ steps.tags.outputs.tag }} - run: ./scripts/build_deploy.sh - - name: Tag Latest - shell: bash - env: - IMG: quay.io/${{ env.QUAY_ORG }}/${{ env.QUAY_IMG_REPO }} - BUILD_IMAGE: false - NEWEST_TAG: ${{ steps.tags.outputs.tag }} - VERSION: latest - run: | - docker tag ${{ env.IMG }}:${{ env.NEWEST_TAG }} ${{ env.IMG }}:${{ env.VERSION }} - # BUILD_IMAGE=false skip the build - ./scripts/build_deploy.sh - - name: Tag Main - shell: bash - env: - IMG: quay.io/${{ env.QUAY_ORG }}/${{ env.QUAY_IMG_REPO }} - BUILD_IMAGE: false - NEWEST_TAG: ${{ steps.tags.outputs.tag }} - VERSION: main - run: | - docker tag ${{ env.IMG }}:${{ env.NEWEST_TAG }} ${{ env.IMG }}:${{ env.VERSION }} - # BUILD_IMAGE=false skip the build - ./scripts/build_deploy.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index faab737a..f7caf3eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -170,11 +170,11 @@ As all the wheels are x86 specific: https://pypi.org/project/ml-metadata/1.14.0/ So it's not even possible to receive code assists. However, after clicking to re-open the project inside an (emulated) DevContainer: -![](doc/Screenshot%202023-11-29%20at%2014.08.12.png) +![](docs/Screenshot%202023-11-29%20at%2014.08.12.png) Then with the given setup MLMD is already installed inside the DevContainer: -![](doc/Screenshot%202023-11-29%20at%2014.10.14.png) +![](docs/Screenshot%202023-11-29%20at%2014.10.14.png) At this point Poetry is already installed as well and can be used to build and run test of the Model Registry Python client. diff --git a/README.md b/README.md index 65006b63..275c0348 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ It provides a model registry domain-specific [api](internal/core/api.go) that is ### Model registry library -For more background on Model Registry Go core library and instructions on using it, please check [getting started guide](./doc/mr_go_library.md). +For more background on Model Registry Go core library and instructions on using it, please check [getting started guide](./docs/mr_go_library.md). ## Development @@ -114,7 +114,7 @@ When shutting down the docker compose, you might want to clean-up the SQLite db The following diagram illustrate testing strategy for the several components in Model Registry project: -![](/doc/Model%20Registry%20Testing%20areas.png) +![](/docs/Model%20Registry%20Testing%20areas.png) Go layers components are tested with Unit Tests written in Go, as well as Integration Tests leveraging Testcontainers. This allows to verify the expected "Core layer" of logical data mapping developed implemented in Go, matches technical expectations. diff --git a/doc/Model Registry Testing areas.drawio b/docs/Model Registry Testing areas.drawio similarity index 100% rename from doc/Model Registry Testing areas.drawio rename to docs/Model Registry Testing areas.drawio diff --git a/doc/Model Registry Testing areas.png b/docs/Model Registry Testing areas.png similarity index 100% rename from doc/Model Registry Testing areas.png rename to docs/Model Registry Testing areas.png diff --git a/doc/Screenshot 2023-11-29 at 14.08.12.png b/docs/Screenshot 2023-11-29 at 14.08.12.png similarity index 100% rename from doc/Screenshot 2023-11-29 at 14.08.12.png rename to docs/Screenshot 2023-11-29 at 14.08.12.png diff --git a/doc/Screenshot 2023-11-29 at 14.10.14.png b/docs/Screenshot 2023-11-29 at 14.10.14.png similarity index 100% rename from doc/Screenshot 2023-11-29 at 14.10.14.png rename to docs/Screenshot 2023-11-29 at 14.10.14.png diff --git a/doc/mr_go_library.md b/docs/mr_go_library.md similarity index 100% rename from doc/mr_go_library.md rename to docs/mr_go_library.md diff --git a/doc/remote_only_packaging_of_MLMD_Python_lib.md b/docs/remote_only_packaging_of_MLMD_Python_lib.md similarity index 100% rename from doc/remote_only_packaging_of_MLMD_Python_lib.md rename to docs/remote_only_packaging_of_MLMD_Python_lib.md From 915bae828d54e7ca759845cfca3c0f6021faad62 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Sat, 27 Jan 2024 04:22:30 +0100 Subject: [PATCH 220/254] Remove ODH tracker.yml (#266) As now covered as Epic in JIRA --- .github/ISSUE_TEMPLATE/tracker.yml | 64 ------------------------------ 1 file changed, 64 deletions(-) delete mode 100644 .github/ISSUE_TEMPLATE/tracker.yml diff --git a/.github/ISSUE_TEMPLATE/tracker.yml b/.github/ISSUE_TEMPLATE/tracker.yml deleted file mode 100644 index 4345f621..00000000 --- a/.github/ISSUE_TEMPLATE/tracker.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: (Internal) Tracker Template -description: Intended to help with a template for tracking larger grouped items. -title: "[Tracker]: " -labels: ["tracker"] -body: - - type: textarea - id: description - attributes: - label: Description - description: A introductory description of the larger task - validations: - required: - true - - type: input - id: branch - attributes: - label: Target Branch - description: What is the feature branch to contain this effort? If not known at this time, replace with `TBD` - placeholder: f/ - validations: - required: true - - type: textarea - id: requirements - attributes: - label: Requirements - description: A series of requirements to consider this tracker complete. - placeholder: | - * P0: Show something - * P2: Allow users to change permissions - validations: - required: true - - type: textarea - id: ux-issues - attributes: - label: Itemized UX Issues - description: | - List the tickets that UX will work on. - - Tip: Using a bullet list will help display links to other tickets by unraveling the name and status of that ticket. - placeholder: | - * #1234 - * Design mocks - Ticket TBD - validations: - required: true - - type: textarea - id: dev-issues - attributes: - label: Itemized Dev Issues - description: | - List the tickets that Development will work on. If unknown at this time, add `TBD` - - Tip: Using a bullet list will help display links to other tickets by unraveling the name and status of that ticket. - placeholder: | - * #1234 - * Implement Table Page - Ticket TBD - validations: - required: true - - type: textarea - id: artifacts - attributes: - label: Related artifacts - description: Any additional artifacts that will help with the tracker goals - validations: - required: false From 22df0a496cc653e1305eb56dbae7a2c652dfdd15 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Sat, 27 Jan 2024 04:24:06 +0100 Subject: [PATCH 221/254] remove auto-add-issue-to-project.yml (#275) --- .../workflows/auto-add-issue-to-project.yml | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 .github/workflows/auto-add-issue-to-project.yml diff --git a/.github/workflows/auto-add-issue-to-project.yml b/.github/workflows/auto-add-issue-to-project.yml deleted file mode 100644 index aa5aac36..00000000 --- a/.github/workflows/auto-add-issue-to-project.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Add Issues to Model Registry ODH board Project -on: - issues: - types: - - opened -jobs: - add-to-project: - name: Add issue to project - runs-on: ubuntu-latest - steps: - - name: Generate github-app token - id: app-token - uses: getsentry/action-github-app-token@v2 - with: - app_id: ${{ secrets.DEVOPS_APP_ID }} - private_key: ${{ secrets.DEVOPS_APP_PRIVATE_KEY }} - - uses: actions/add-to-project@v0.5.0 - with: - project-url: https://github.com/orgs/opendatahub-io/projects/49 - github-token: ${{ steps.app-token.outputs.token }} From d6f43009ab4ae1a77ac0c9759ac3a9ff916301f7 Mon Sep 17 00:00:00 2001 From: tonyxrmdavidson Date: Sat, 27 Jan 2024 03:37:14 +0000 Subject: [PATCH 222/254] Updated depreciated commands to use RETURN Keywords (#268) --- test/robot/MRkeywords.resource | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/robot/MRkeywords.resource b/test/robot/MRkeywords.resource index 7cd7f8cb..6c26fcbe 100644 --- a/test/robot/MRkeywords.resource +++ b/test/robot/MRkeywords.resource @@ -21,7 +21,7 @@ I create a RegisteredModel having ${result} Upsert Registered Model ${data} Log to console ${result} END - [return] ${result} + RETURN ${result} I create a RegisteredModel @@ -34,7 +34,7 @@ I create a RegisteredModel ${result} Upsert Registered Model ${payload} Log to console ${result} END - [return] ${result} + RETURN ${result} I create a child ModelVersion having @@ -49,7 +49,7 @@ I create a child ModelVersion having ${result} Upsert Model Version ${data} ${registeredModelID} Log to console ${result} END - [return] ${result} + RETURN ${result} I create a child ModelVersion @@ -63,7 +63,7 @@ I create a child ModelVersion ${result} Upsert Model Version ${payload} ${registeredModelID} Log to console ${result} END - [return] ${result} + RETURN ${result} I create a child ModelArtifact having @@ -79,7 +79,7 @@ I create a child ModelArtifact having ${result} Upsert Model Artifact ${data} ${modelversionId} Log to console ${result} END - [return] ${result} + RETURN ${result} I create a child ModelArtifact @@ -92,7 +92,7 @@ I create a child ModelArtifact ${result} Upsert Model Artifact ${payload} ${modelversionId} Log to console ${result} END - [return] ${result} + RETURN ${result} I get RegisteredModelByID @@ -105,7 +105,7 @@ I get RegisteredModelByID Log to console ${MODE} Fail Not Implemented END - [return] ${result} + RETURN ${result} I get ModelVersionByID @@ -118,7 +118,7 @@ I get ModelVersionByID Log to console ${MODE} Fail Not Implemented END - [return] ${result} + RETURN ${result} I get ModelArtifactByID @@ -131,4 +131,4 @@ I get ModelArtifactByID Log to console ${MODE} Fail Not Implemented END - [return] ${result} + RETURN ${result} From a4b0ccd83ee2b9385c9efe37d647cba40372e16b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 10:36:11 +0100 Subject: [PATCH 223/254] build(deps): bump github.com/google/uuid from 1.5.0 to 1.6.0 (#279) Bumps [github.com/google/uuid](https://github.com/google/uuid) from 1.5.0 to 1.6.0. - [Release notes](https://github.com/google/uuid/releases) - [Changelog](https://github.com/google/uuid/blob/master/CHANGELOG.md) - [Commits](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) --- updated-dependencies: - dependency-name: github.com/google/uuid dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 66250a1a..567d3ffa 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/go-ole/go-ole v1.2.6 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0 github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/compress v1.17.0 // indirect diff --git a/go.sum b/go.sum index 50b6b08b..4cb02102 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= From 4575b5b270ac97ef5c91bacead9b4002f9f6ac86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 10:42:23 +0100 Subject: [PATCH 224/254] build(deps): bump google.golang.org/grpc from 1.60.1 to 1.61.0 (#280) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.60.1 to 1.61.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.60.1...v1.61.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 567d3ffa..e3f3eb82 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 github.com/testcontainers/testcontainers-go v0.26.0 - google.golang.org/grpc v1.60.1 + google.golang.org/grpc v1.61.0 google.golang.org/protobuf v1.32.0 ) diff --git a/go.sum b/go.sum index 4cb02102..57f0c586 100644 --- a/go.sum +++ b/go.sum @@ -227,8 +227,8 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= +google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= From 199f56b56826018ac9b9dcab676ac3863f31b1e6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 10:42:39 +0100 Subject: [PATCH 225/254] build(deps): bump codecov/codecov-action from 3.1.4 to 3.1.5 (#281) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.4 to 3.1.5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.4...v3.1.5) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/python-tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2fdbcdd3..87e249da 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,7 @@ jobs: - name: Unit tests run: make test-cover - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3.1.4 + uses: codecov/codecov-action@v3.1.5 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 7f74c350..38b4cfe7 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -71,7 +71,7 @@ jobs: fi - name: Upload coverage report - uses: codecov/codecov-action@v3.1.4 + uses: codecov/codecov-action@v3.1.5 if: always() && matrix.session == 'tests' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From dd688667e7c8417f8d811dacb204870cb8bb8273 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 10:48:01 +0100 Subject: [PATCH 226/254] build(deps): bump helm/kind-action from 1.4.0 to 1.8.0 (#282) Bumps [helm/kind-action](https://github.com/helm/kind-action) from 1.4.0 to 1.8.0. - [Release notes](https://github.com/helm/kind-action/releases) - [Commits](https://github.com/helm/kind-action/compare/v1.4.0...v1.8.0) --- updated-dependencies: - dependency-name: helm/kind-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-image-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index d4a18ad9..a6737e0d 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -35,7 +35,7 @@ jobs: VERSION: ${{ steps.tags.outputs.tag }} run: ./scripts/build_deploy.sh - name: Start Kind Cluster - uses: helm/kind-action@v1.4.0 + uses: helm/kind-action@v1.8.0 - name: Load Local Registry Test Image env: IMG: "quay.io/opendatahub/model-registry:${{ steps.tags.outputs.tag }}" From 13a24ab320c99fe409558daf7665c8cf2fa8ff66 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Wed, 31 Jan 2024 08:43:18 +0100 Subject: [PATCH 227/254] update instructions for remote-only MLMD Python lib (#283) --- CONTRIBUTING.md | 11 +++++++++++ clients/python/pyproject.toml | 6 ++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f7caf3eb..b768c228 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -83,6 +83,17 @@ This colima setups allows to: - launch Integration tests in Go (used in Core go layer) with Testcontainers for Go - launch DevContainer to be able to install MLMD python wheel dependency (which is x86 specific) +## Remote-only MLMD Python library + +The Model Registry Python client wraps `ml-metadata` python dependency (which is [x86 specific](https://pypi.org/project/ml-metadata/#files)). + +When developing and contributing to the Model Registry Python client using Apple-silicon/ARM-based computers, +it can be helpful to evaluate using locally this soft-fork of the upstream MLMD library supporting only remote gRPC connections: +https://github.com/opendatahub-io/ml-metadata/releases/tag/v1.14.0%2Bremote.1 + +This dependency can be substituted in the [clients/python/pyproject.toml](clients/python/pyproject.toml) and installed locally with `poetry lock`. +It is recommended not to check-in this substitution, only helpful for local development while using Apple-silicon/ARM-based computers. + ## DevContainer Using a [DevContainer](https://containers.dev) is helpful to develop with the Model Registry Python client, since it needs to wrap MLMD python dependency (which is [x86 specific](https://pypi.org/project/ml-metadata/#files)). diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 346b34fd..656792f6 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -10,10 +10,8 @@ readme = "README.md" python = ">= 3.9, < 3.11" attrs = "^21.0" ml-metadata = "^1.14.0" -# Testcontainers for python, remote mlmd grpc tested with: -# ml-metadata = { url = "https://github.com/tarilabs/ml-metadata/releases/download/1.14.0/ml_metadata-1.14.0-py3-none-any.whl" } -# or might consider as well: -# ml-metadata = { url = "https://github.com/tarilabs/ml-metadata-remote/releases/download/1.14.0/ml_metadata-1.14.0-py3-none-any.whl" } +# you might consider using locally the following alternative, when developing on Apple-silicon/ARM-based computers: +# ml-metadata = { url = "https://github.com/opendatahub-io/ml-metadata/releases/download/v1.14.0%2Bremote.1/ml_metadata-1.14.0+remote.1-py3-none-any.whl" } typing-extensions = "^4.8" huggingface-hub = { version = "^0.20.1", optional = true } From 3c6b27943950f7d120477e4737bf7851d399975e Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Fri, 2 Feb 2024 13:55:55 +0100 Subject: [PATCH 228/254] fix test_hf_import test_hf_import_missing_author (#287) likely due to HF maintenance of model ids located at the root-level --- clients/python/tests/test_client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index fe3c9e66..a88f8d07 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -70,7 +70,7 @@ def test_get(mr_client: ModelRegistry): def test_hf_import(mr_client: ModelRegistry): pytest.importorskip("huggingface_hub") - name = "gpt2" + name = "openai-community/gpt2" version = "1.2.3" assert mr_client.register_hf_model( @@ -87,13 +87,13 @@ def test_hf_import(mr_client: ModelRegistry): def test_hf_import_missing_author(mr_client: ModelRegistry): pytest.importorskip("huggingface_hub") - name = "gpt2" + name = "bert-base-uncased" version = "1.2.3" with pytest.warns(match=r".*author is unknown.*"): assert mr_client.register_hf_model( name, - "onnx/decoder_model.onnx", + "model.onnx", version=version, model_format_name="test format", model_format_version="test version", From c34041a4712bb2532f0de52845273fc4a846eb98 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:04:55 +0100 Subject: [PATCH 229/254] build(deps): bump github.com/opencontainers/runc from 1.1.5 to 1.1.12 (#284) Bumps [github.com/opencontainers/runc](https://github.com/opencontainers/runc) from 1.1.5 to 1.1.12. - [Release notes](https://github.com/opencontainers/runc/releases) - [Changelog](https://github.com/opencontainers/runc/blob/v1.1.12/CHANGELOG.md) - [Commits](https://github.com/opencontainers/runc/compare/v1.1.5...v1.1.12) --- updated-dependencies: - dependency-name: github.com/opencontainers/runc dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 44 ++------------------------------------------ 2 files changed, 3 insertions(+), 43 deletions(-) diff --git a/go.mod b/go.mod index e3f3eb82..f25c4fd5 100644 --- a/go.mod +++ b/go.mod @@ -56,7 +56,7 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc5 // indirect - github.com/opencontainers/runc v1.1.5 // indirect + github.com/opencontainers/runc v1.1.12 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect diff --git a/go.sum b/go.sum index 57f0c586..07009374 100644 --- a/go.sum +++ b/go.sum @@ -3,27 +3,20 @@ dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -34,10 +27,8 @@ github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= @@ -47,8 +38,6 @@ github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= @@ -56,7 +45,6 @@ github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwm github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -71,10 +59,7 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM= github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -84,22 +69,18 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= github.com/opencontainers/image-spec v1.1.0-rc5/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= -github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= -github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss= +github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8= github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -110,21 +91,17 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shirou/gopsutil/v3 v3.23.9 h1:ZI5bWVeu2ep4/DIxB4U9okeYJ7zp/QLTO4auRb/ty/E= github.com/shirou/gopsutil/v3 v3.23.9/go.mod h1:x/NWSb71eMcjFIO0vhyGW5nZ7oSIgVjrCnADckb85GA= github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= @@ -142,7 +119,6 @@ github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMV github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -151,16 +127,12 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/testcontainers/testcontainers-go v0.26.0 h1:uqcYdoOHBy1ca7gKODfBd9uTHVK3a7UL848z09MVZ0c= github.com/testcontainers/testcontainers-go v0.26.0/go.mod h1:ICriE9bLX5CLxL9OFQ2N+2N+f+803LNJ1utJb1+Inx0= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= @@ -182,7 +154,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -191,25 +162,16 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -231,14 +193,12 @@ google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 041dc295ecfad4139f2c2bd8c89d7591e4d8152f Mon Sep 17 00:00:00 2001 From: tonyxrmdavidson Date: Fri, 2 Feb 2024 14:19:33 +0000 Subject: [PATCH 230/254] update to python/client README to give commands for running python tests on a mac with M2 (#272) resolved comments from isinyaaa and tarilabs Update wording and explanations after resolved comments from isinyaaa and tarilabs --- clients/python/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/clients/python/README.md b/clients/python/README.md index c78d55e3..f088f844 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -78,4 +78,20 @@ Common tasks, such as building documentation and running tests, can be executed Use `nox -l` to list sessions and execute them using `nox -s [session]`. +### Running Locally on Mac M1 or M2 (arm64 architecture) + +If you want run tests locally you will need to set up a colima develeopment environment using the instructions [here](https://github.com/opendatahub-io/model-registry/blob/main/CONTRIBUTING.md#colima) + +You will also have to change the package source to one compatible with ARM64 architecture. This can be actioned by uncommenting lines 14 or 15 in the pyproject.toml file. Run the following command after you have uncommented the line. + +```sh +poetry lock +``` +Use the following commands to directly run the tests with individual test output. Alternatively you can use the nox session commands above. + +```sh +poetry install +poetry run pytest -v +``` + From 0e681d1b223f68bff2af5b522df1ca65fb810045 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 09:53:47 +0100 Subject: [PATCH 231/254] build(deps): bump arduino/setup-protoc from 2 to 3 (#290) Bumps [arduino/setup-protoc](https://github.com/arduino/setup-protoc) from 2 to 3. - [Release notes](https://github.com/arduino/setup-protoc/releases) - [Commits](https://github.com/arduino/setup-protoc/compare/v2...v3) --- updated-dependencies: - dependency-name: arduino/setup-protoc dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 87e249da..07ab594e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: with: go-version: '1.19' - name: Install Protoc - uses: arduino/setup-protoc@v2 + uses: arduino/setup-protoc@v3 with: version: "24.3" repo-token: ${{ secrets.GITHUB_TOKEN }} From 212d47f9721c54a38200913c6a14e2788d7ea3bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:17:06 +0100 Subject: [PATCH 232/254] build(deps): bump codecov/codecov-action from 3.1.5 to 4.0.1 (#291) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.5 to 4.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/v3.1.5...v4.0.1) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/python-tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 07ab594e..b72e33b9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -53,7 +53,7 @@ jobs: - name: Unit tests run: make test-cover - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3.1.5 + uses: codecov/codecov-action@v4.0.1 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 38b4cfe7..8e8a3c48 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -71,7 +71,7 @@ jobs: fi - name: Upload coverage report - uses: codecov/codecov-action@v3.1.5 + uses: codecov/codecov-action@v4.0.1 if: always() && matrix.session == 'tests' env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From c893ea861a11852c74faad9e8aaa3a235a02ac66 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Wed, 31 Jan 2024 21:03:55 -0300 Subject: [PATCH 233/254] add pre-commit hooks Closes: #277 Signed-off-by: Isabella Basso do Amaral --- .github/workflows/build-and-push-image.yml | 3 - .github/workflows/build-image-pr.yml | 3 - .github/workflows/build.yml | 2 - .github/workflows/python-release.yml | 10 - .github/workflows/python-tests.yml | 12 - .github/workflows/run-robot-tests.yaml | 2 +- .pre-commit-config.yaml | 28 + CONTRIBUTING.md | 4 +- Makefile | 2 +- README.md | 8 +- api/openapi/model-registry.yaml | 1318 +++++++---------- .../python/src/model_registry/store/base.py | 9 +- cmd/proxy.go | 2 +- cmd/root.go | 16 +- docker-compose-local.yaml | 6 +- docker-compose.yaml | 4 +- docs/mr_go_library.md | 2 +- ...emote_only_packaging_of_MLMD_Python_lib.md | 2 +- .../server/openapi/.openapi-generator/VERSION | 2 +- patches/type_asserts.patch | 3 +- scripts/build_deploy.sh | 2 +- scripts/gen_type_asserts.sh | 4 +- templates/go-server/model.mustache | 2 +- test/python/test_mlmetadata.py | 20 +- test/robot/MRandLogicalModel.robot | 6 +- test/robot/Setup.resource | 6 +- test/robot/UserStory.robot | 6 +- test/robot/requirements.txt | 2 +- 28 files changed, 648 insertions(+), 838 deletions(-) create mode 100644 .pre-commit-config.yaml diff --git a/.github/workflows/build-and-push-image.yml b/.github/workflows/build-and-push-image.yml index 0648b3e8..216943aa 100644 --- a/.github/workflows/build-and-push-image.yml +++ b/.github/workflows/build-and-push-image.yml @@ -1,5 +1,4 @@ name: Container image build and tag - on: push: branches: @@ -14,14 +13,12 @@ on: - '.github/ISSUE_TEMPLATE/**' - '.github/dependabot.yml' - 'docs/**' - env: QUAY_ORG: opendatahub QUAY_IMG_REPO: model-registry QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} QUAY_PASSWORD: ${{ secrets.QUAY_PASSWORD }} PUSH_IMAGE: true - jobs: build-image: runs-on: ubuntu-latest diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index a6737e0d..98f5de1f 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -1,5 +1,4 @@ name: Test container image build and deployment - on: pull_request: paths-ignore: @@ -11,12 +10,10 @@ on: - '.github/dependabot.yml' - 'docs/**' - 'clients/python/**' - env: QUAY_IMG_REPO: model-registry PUSH_IMAGE: false BRANCH: ${{ github.base_ref }} - jobs: build-and-test-image: runs-on: ubuntu-latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b72e33b9..901d3489 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,5 +1,4 @@ name: Build - on: push: branches: @@ -15,7 +14,6 @@ on: - '.github/dependabot.yml' - 'docs/**' - 'scripts/**' - jobs: build: runs-on: ubuntu-latest diff --git a/.github/workflows/python-release.yml b/.github/workflows/python-release.yml index dc529ced..6f4da8d7 100644 --- a/.github/workflows/python-release.yml +++ b/.github/workflows/python-release.yml @@ -1,42 +1,34 @@ name: Release Python client - on: push: tags: - py-v* workflow_dispatch: - jobs: release: name: Release runs-on: ubuntu-latest permissions: id-token: write - env: FORCE_COLOR: "1" - steps: - name: Check out the repository uses: actions/checkout@v4 with: fetch-depth: 0 - - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.10" - - name: Upgrade pip run: | pip install --constraint=.github/workflows/constraints.txt pip pip --version - - name: Install Poetry run: | pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry poetry --version - - name: Check version working-directory: clients/python run: | @@ -46,12 +38,10 @@ jobs: echo "::error title='$LATEST_TAG tag does not match project version'::" exit 1 fi - - name: Build package working-directory: clients/python run: | poetry build --ansi - - name: Publish package on PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml index 8e8a3c48..323575a7 100644 --- a/.github/workflows/python-tests.yml +++ b/.github/workflows/python-tests.yml @@ -1,11 +1,9 @@ name: Python workflows - on: push: branches: - "main" pull_request: - jobs: tests: name: ${{ matrix.session }} ${{ matrix.python }} @@ -18,26 +16,21 @@ jobs: include: - python: "3.9" session: tests - env: NOXSESSION: ${{ matrix.session }} FORCE_COLOR: "1" PRE_COMMIT_COLOR: "always" - steps: - name: Check out the repository uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - - name: Upgrade pip run: | pip install --constraint=.github/workflows/constraints.txt pip pip --version - - name: Upgrade pip in virtual environments shell: python run: | @@ -46,18 +39,15 @@ jobs: with open(os.environ["GITHUB_ENV"], mode="a") as io: print(f"VIRTUALENV_PIP={pip.__version__}", file=io) - - name: Install Poetry run: | pipx install --pip-args=--constraint=.github/workflows/constraints.txt poetry poetry --version - - name: Install Nox run: | pipx install --pip-args=--constraint=.github/workflows/constraints.txt nox pipx inject --pip-args=--constraint=.github/workflows/constraints.txt nox nox-poetry nox --version - - name: Run Nox working-directory: clients/python run: | @@ -69,7 +59,6 @@ jobs: else nox --python=${{ matrix.python }} fi - - name: Upload coverage report uses: codecov/codecov-action@v4.0.1 if: always() && matrix.session == 'tests' @@ -78,7 +67,6 @@ jobs: with: files: coverage.xml fail_ci_if_error: true - - name: Upload documentation if: matrix.session == 'docs-build' uses: actions/upload-artifact@v4 diff --git a/.github/workflows/run-robot-tests.yaml b/.github/workflows/run-robot-tests.yaml index ea824706..029b4040 100644 --- a/.github/workflows/run-robot-tests.yaml +++ b/.github/workflows/run-robot-tests.yaml @@ -62,4 +62,4 @@ jobs: # Shutdown docker compose with locally build image from current code - name: Shutdown docker compose with local image # Shutdown docker compose running in the background - run: docker compose -f docker-compose-local.yaml down \ No newline at end of file + run: docker compose -f docker-compose-local.yaml down diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..b40ec072 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,28 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-added-large-files + - id: check-ast + - id: check-case-conflict + - id: check-docstring-first + - id: check-executables-have-shebangs + - id: check-json + - id: check-merge-conflict + # TODO: (goverter 1.3.2) generated files are marked 777 (see: https://github.com/jmattheis/goverter/issues/128) + # - id: check-shebang-scripts-are-executable + - id: check-symlinks + - id: debug-statements + - id: detect-private-key + - id: end-of-file-fixer + - id: trailing-whitespace + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.13 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format + - repo: https://github.com/google/yamlfmt + rev: v0.10.0 + hooks: + - id: yamlfmt diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b768c228..793cf3ff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -73,7 +73,7 @@ colima start --vz-rosetta --vm-type vz --arch x86_64 --cpu 4 --memory 8 To use with *Testcontainers for Go* you can use these commands: ``` -export DOCKER_HOST="unix://${HOME}/.colima/default/docker.sock" +export DOCKER_HOST="unix://${HOME}/.colima/default/docker.sock" export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE="/var/run/docker.sock" ``` @@ -189,4 +189,4 @@ Then with the given setup MLMD is already installed inside the DevContainer: At this point Poetry is already installed as well and can be used to build and run test of the Model Registry Python client. - \ No newline at end of file + diff --git a/Makefile b/Makefile index a64f5e6e..c4a720bc 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ IMG := ${IMG_REGISTRY}/$(IMG_ORG)/$(IMG_REPO) model-registry: build # clean the ml-metadata protos and trigger a fresh new build which downloads -# ml-metadata protos based on specified MLMD_VERSION +# ml-metadata protos based on specified MLMD_VERSION .PHONY: update/ml_metadata update/ml_metadata: clean/ml_metadata clean build diff --git a/README.md b/README.md index 275c0348..734b82a5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ The proxy service implements the OpenAPI defined in [model-registry.yaml](api/op ## Model Registry Core -The model registry core is the layer which implements the core/business logic by interacting with the underlying ml-metadata server. +The model registry core is the layer which implements the core/business logic by interacting with the underlying ml-metadata server. It provides a model registry domain-specific [api](internal/core/api.go) that is in charge to proxy all, appropriately transformed, requests to ml-metadata using gRPC calls. ### Model registry library @@ -89,11 +89,11 @@ Subsequent builds will re-use the cached tools layer. The following command starts the proxy server: ```shell -docker run -d -p ::8080 --user : --name server model-registry proxy -n 0.0.0.0 +docker run -d -p ::8080 --user : --name server model-registry proxy -n 0.0.0.0 ``` -Where, ``, ``, and `` are the same as in the migrate command above. -And `` and `` are the local ip and port to use to expose the container's default `8080` listening port. +Where, ``, ``, and `` are the same as in the migrate command above. +And `` and `` are the local ip and port to use to expose the container's default `8080` listening port. The server listens on `localhost` by default, hence the `-n 0.0.0.0` option allows the server port to be exposed. #### Running model registry & ml-metadata diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index ff2940a0..72c0c6ad 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -5,70 +5,59 @@ info: description: REST API for Model Registry to create and manage ML model metadata license: name: Apache 2.0 - url: 'https://www.apache.org/licenses/LICENSE-2.0' + url: "https://www.apache.org/licenses/LICENSE-2.0" servers: - - - url: 'https://localhost:8080' - - - url: 'http://localhost:8080' + - url: "https://localhost:8080" + - url: "http://localhost:8080" paths: /api/model_registry/v1alpha1/model_artifact: summary: Path used to search for a modelartifact. description: >- - The REST endpoint/path used to search for a `ModelArtifact` entity. This path contains a `GET` - operation to perform the find task. + The REST endpoint/path used to search for a `ModelArtifact` entity. This path contains a `GET` operation to perform the find task. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ModelArtifactResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelArtifactResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: findModelArtifact summary: Get a ModelArtifact that matches search parameters. description: Gets the details of a single instance of a `ModelArtifact` that matches search parameters. parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' - - - $ref: '#/components/parameters/parentResourceID' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" + - $ref: "#/components/parameters/parentResourceID" /api/model_registry/v1alpha1/model_artifacts: summary: Path used to manage the list of modelartifacts. description: >- - The REST endpoint/path used to list and create zero or more `ModelArtifact` entities. This path - contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + The REST endpoint/path used to list and create zero or more `ModelArtifact` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/ModelArtifactListResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelArtifactListResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getModelArtifacts summary: List All ModelArtifacts description: Gets a list of all `ModelArtifact` entities. @@ -78,40 +67,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ModelArtifactCreate' + $ref: "#/components/schemas/ModelArtifactCreate" required: true tags: - ModelRegistryService responses: - '201': - $ref: '#/components/responses/ModelArtifactResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "201": + $ref: "#/components/responses/ModelArtifactResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createModelArtifact summary: Create a ModelArtifact description: Creates a new instance of a `ModelArtifact`. - '/api/model_registry/v1alpha1/model_artifacts/{modelartifactId}': + "/api/model_registry/v1alpha1/model_artifacts/{modelartifactId}": summary: Path used to manage a single ModelArtifact. description: >- - The REST endpoint/path used to get, update, and delete single instances of an `ModelArtifact`. - This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and - delete tasks, respectively. + The REST endpoint/path used to get, update, and delete single instances of an `ModelArtifact`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks, respectively. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ModelArtifactResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelArtifactResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getModelArtifact summary: Get a ModelArtifact description: Gets the details of a single instance of a `ModelArtifact`. @@ -121,27 +108,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ModelArtifactUpdate' + $ref: "#/components/schemas/ModelArtifactUpdate" required: true tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ModelArtifactResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelArtifactResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: updateModelArtifact summary: Update a ModelArtifact description: Updates an existing `ModelArtifact`. parameters: - - - name: modelartifactId + - name: modelartifactId description: A unique identifier for a `ModelArtifact`. schema: type: string @@ -150,27 +136,22 @@ paths: /api/model_registry/v1alpha1/model_versions: summary: Path used to manage the list of modelversions. description: >- - The REST endpoint/path used to list and create zero or more `ModelVersion` entities. This path - contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + The REST endpoint/path used to list and create zero or more `ModelVersion` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/ModelVersionListResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelVersionListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getModelVersions summary: List All ModelVersions description: Gets a list of all `ModelVersion` entities. @@ -180,40 +161,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ModelVersionCreate' + $ref: "#/components/schemas/ModelVersionCreate" required: true tags: - ModelRegistryService responses: - '201': - $ref: '#/components/responses/ModelVersionResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "201": + $ref: "#/components/responses/ModelVersionResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createModelVersion summary: Create a ModelVersion description: Creates a new instance of a `ModelVersion`. - '/api/model_registry/v1alpha1/model_versions/{modelversionId}': + "/api/model_registry/v1alpha1/model_versions/{modelversionId}": summary: Path used to manage a single ModelVersion. description: >- - The REST endpoint/path used to get, update, and delete single instances of an `ModelVersion`. - This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and - delete tasks, respectively. + The REST endpoint/path used to get, update, and delete single instances of an `ModelVersion`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks, respectively. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ModelVersionResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelVersionResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getModelVersion summary: Get a ModelVersion description: Gets the details of a single instance of a `ModelVersion`. @@ -223,27 +202,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ModelVersion' + $ref: "#/components/schemas/ModelVersion" required: true tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ModelVersionResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelVersionResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: updateModelVersion summary: Update a ModelVersion description: Updates an existing `ModelVersion`. parameters: - - - name: modelversionId + - name: modelversionId description: A unique identifier for a `ModelVersion`. schema: type: string @@ -252,52 +230,44 @@ paths: /api/model_registry/v1alpha1/registered_model: summary: Path used to search for a registeredmodel. description: >- - The REST endpoint/path used to search for a `RegisteredModel` entity. This path contains a `GET` - operation to perform the find task. + The REST endpoint/path used to search for a `RegisteredModel` entity. This path contains a `GET` operation to perform the find task. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/RegisteredModelResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/RegisteredModelResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: findRegisteredModel summary: Get a RegisteredModel that matches search parameters. description: Gets the details of a single instance of a `RegisteredModel` that matches search parameters. parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" /api/model_registry/v1alpha1/registered_models: summary: Path used to manage the list of registeredmodels. description: >- - The REST endpoint/path used to list and create zero or more `RegisteredModel` entities. This path - contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + The REST endpoint/path used to list and create zero or more `RegisteredModel` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/RegisteredModelListResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/RegisteredModelListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getRegisteredModels summary: List All RegisteredModels description: Gets a list of all `RegisteredModel` entities. @@ -307,40 +277,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/RegisteredModelCreate' + $ref: "#/components/schemas/RegisteredModelCreate" required: true tags: - ModelRegistryService responses: - '201': - $ref: '#/components/responses/RegisteredModelResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "201": + $ref: "#/components/responses/RegisteredModelResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createRegisteredModel summary: Create a RegisteredModel description: Creates a new instance of a `RegisteredModel`. - '/api/model_registry/v1alpha1/registered_models/{registeredmodelId}': + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}": summary: Path used to manage a single RegisteredModel. description: >- - The REST endpoint/path used to get, update, and delete single instances of an `RegisteredModel`. - This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and - delete tasks, respectively. + The REST endpoint/path used to get, update, and delete single instances of an `RegisteredModel`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks, respectively. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/RegisteredModelResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/RegisteredModelResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getRegisteredModel summary: Get a RegisteredModel description: Gets the details of a single instance of a `RegisteredModel`. @@ -350,63 +318,54 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/RegisteredModelUpdate' + $ref: "#/components/schemas/RegisteredModelUpdate" required: true tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/RegisteredModelResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/RegisteredModelResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: updateRegisteredModel summary: Update a RegisteredModel description: Updates an existing `RegisteredModel`. parameters: - - - name: registeredmodelId + - name: registeredmodelId description: A unique identifier for a `RegisteredModel`. schema: type: string in: path required: true - '/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts': + "/api/model_registry/v1alpha1/model_versions/{modelversionId}/artifacts": summary: Path used to manage the list of artifacts for a modelversion. description: >- - The REST endpoint/path used to list and create zero or more `Artifact` entities for a - `ModelVersion`. This path contains a `GET` and `POST` operation to perform the list and create - tasks, respectively. + The REST endpoint/path used to list and create zero or more `Artifact` entities for a `ModelVersion`. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/ArtifactListResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ArtifactListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getModelVersionArtifacts summary: List All ModelVersion's artifacts description: Gets a list of all `Artifact` entities for the `ModelVersion`. @@ -416,65 +375,56 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/Artifact' + $ref: "#/components/schemas/Artifact" required: true tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ArtifactResponse' - '201': - $ref: '#/components/responses/ArtifactResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ArtifactResponse" + "201": + $ref: "#/components/responses/ArtifactResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createModelVersionArtifact summary: Create an Artifact in a ModelVersion description: Creates a new instance of an Artifact if needed and associates it with `ModelVersion`. parameters: - - - name: modelversionId + - name: modelversionId description: A unique identifier for a `ModelVersion`. schema: type: string in: path required: true - '/api/model_registry/v1alpha1/registered_models/{registeredmodelId}/versions': + "/api/model_registry/v1alpha1/registered_models/{registeredmodelId}/versions": summary: Path used to manage the list of modelversions for a registeredmodel. description: >- - The REST endpoint/path used to list and create zero or more `ModelVersion` entities for a - `RegisteredModel`. This path contains a `GET` and `POST` operation to perform the list and create - tasks, respectively. + The REST endpoint/path used to list and create zero or more `ModelVersion` entities for a `RegisteredModel`. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/ModelVersionListResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelVersionListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getRegisteredModelVersions summary: List All RegisteredModel's ModelVersions description: Gets a list of all `ModelVersion` entities for the `RegisteredModel`. @@ -484,27 +434,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ModelVersion' + $ref: "#/components/schemas/ModelVersion" required: true tags: - ModelRegistryService responses: - '201': - $ref: '#/components/responses/ModelVersionResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "201": + $ref: "#/components/responses/ModelVersionResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createRegisteredModelVersion summary: Create a ModelVersion in RegisteredModel description: Creates a new instance of a `ModelVersion`. parameters: - - - name: registeredmodelId + - name: registeredmodelId description: A unique identifier for a `RegisteredModel`. schema: type: string @@ -513,48 +462,43 @@ paths: /api/model_registry/v1alpha1/inference_service: summary: Path used to manage an instance of inferenceservice. description: >- - The REST endpoint/path used to list and create zero or more `InferenceService` entities. This - path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + The REST endpoint/path used to list and create zero or more `InferenceService` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/InferenceServiceResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/InferenceServiceResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: findInferenceService summary: Get an InferenceServices that matches search parameters. description: Gets the details of a single instance of `InferenceService` that matches search parameters. parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' - '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}': + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}": summary: Path used to manage a single InferenceService. description: >- - The REST endpoint/path used to get, update, and delete single instances of an `InferenceService`. - This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and - delete tasks, respectively. + The REST endpoint/path used to get, update, and delete single instances of an `InferenceService`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks, respectively. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/InferenceServiceResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/InferenceServiceResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getInferenceService summary: Get a InferenceService description: Gets the details of a single instance of a `InferenceService`. @@ -564,27 +508,26 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/InferenceServiceUpdate' + $ref: "#/components/schemas/InferenceServiceUpdate" required: true tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/InferenceServiceResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/InferenceServiceResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: updateInferenceService summary: Update a InferenceService description: Updates an existing `InferenceService`. parameters: - - - name: inferenceserviceId + - name: inferenceserviceId description: A unique identifier for a `InferenceService`. schema: type: string @@ -593,31 +536,26 @@ paths: /api/model_registry/v1alpha1/inference_services: summary: Path used to manage the list of inferenceservices. description: >- - The REST endpoint/path used to list and create zero or more `InferenceService` entities. This - path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + The REST endpoint/path used to list and create zero or more `InferenceService` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/InferenceServiceListResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/InferenceServiceListResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getInferenceServices summary: List All InferenceServices description: Gets a list of all `InferenceService` entities. @@ -627,71 +565,63 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/InferenceServiceCreate' + $ref: "#/components/schemas/InferenceServiceCreate" required: true tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/InferenceServiceResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/InferenceServiceResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createInferenceService summary: Create a InferenceService description: Creates a new instance of a `InferenceService`. /api/model_registry/v1alpha1/serving_environment: summary: Path used to find a servingenvironment. description: >- - The REST endpoint/path used to search for a `ServingEnvironment` entity. This path contains a - `GET` operation to perform the find task. + The REST endpoint/path used to search for a `ServingEnvironment` entity. This path contains a `GET` operation to perform the find task. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ServingEnvironmentResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ServingEnvironmentResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: findServingEnvironment summary: Find ServingEnvironment description: Finds a `ServingEnvironment` entity that matches query parameters. parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" /api/model_registry/v1alpha1/serving_environments: summary: Path used to manage the list of servingenvironments. description: >- - The REST endpoint/path used to list and create zero or more `ServingEnvironment` entities. This - path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. + The REST endpoint/path used to list and create zero or more `ServingEnvironment` entities. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/ServingEnvironmentListResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ServingEnvironmentListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getServingEnvironments summary: List All ServingEnvironments description: Gets a list of all `ServingEnvironment` entities. @@ -701,40 +631,38 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ServingEnvironmentCreate' + $ref: "#/components/schemas/ServingEnvironmentCreate" required: true tags: - ModelRegistryService responses: - '201': - $ref: '#/components/responses/ServingEnvironmentResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' + "201": + $ref: "#/components/responses/ServingEnvironmentResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createServingEnvironment summary: Create a ServingEnvironment description: Creates a new instance of a `ServingEnvironment`. - '/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}': + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}": summary: Path used to manage a single ServingEnvironment. description: >- - The REST endpoint/path used to get, update, and delete single instances of an - `ServingEnvironment`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform - the get, update, and delete tasks, respectively. + The REST endpoint/path used to get, update, and delete single instances of an `ServingEnvironment`. This path contains `GET`, `PUT`, and `DELETE` operations used to perform the get, update, and delete tasks, respectively. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ServingEnvironmentResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ServingEnvironmentResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getServingEnvironment summary: Get a ServingEnvironment description: Gets the details of a single instance of a `ServingEnvironment`. @@ -744,63 +672,54 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ServingEnvironmentUpdate' + $ref: "#/components/schemas/ServingEnvironmentUpdate" required: true tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ServingEnvironmentResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ServingEnvironmentResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: updateServingEnvironment summary: Update a ServingEnvironment description: Updates an existing `ServingEnvironment`. parameters: - - - name: servingenvironmentId + - name: servingenvironmentId description: A unique identifier for a `ServingEnvironment`. schema: type: string in: path required: true - '/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}/inference_services': + "/api/model_registry/v1alpha1/serving_environments/{servingenvironmentId}/inference_services": summary: Path used to manage the list of `InferenceServices` for a `ServingEnvironment`. description: >- - The REST endpoint/path used to list and create zero or more `InferenceService` entities for a - `ServingEnvironment`. This path contains a `GET` and `POST` operation to perform the list and - create tasks, respectively. + The REST endpoint/path used to list and create zero or more `InferenceService` entities for a `ServingEnvironment`. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/InferenceServiceListResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/InferenceServiceListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getEnvironmentInferenceServices summary: List All ServingEnvironment's InferenceServices description: Gets a list of all `InferenceService` entities for the `ServingEnvironment`. @@ -810,63 +729,54 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/InferenceServiceCreate' + $ref: "#/components/schemas/InferenceServiceCreate" required: true tags: - ModelRegistryService responses: - '201': - $ref: '#/components/responses/InferenceServiceResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "201": + $ref: "#/components/responses/InferenceServiceResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createEnvironmentInferenceService summary: Create a InferenceService in ServingEnvironment description: Creates a new instance of a `InferenceService`. parameters: - - - name: servingenvironmentId + - name: servingenvironmentId description: A unique identifier for a `ServingEnvironment`. schema: type: string in: path required: true - '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/serves': + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/serves": summary: Path used to manage the list of `ServeModels` for a `InferenceService`. description: >- - The REST endpoint/path used to list and create zero or more `ServeModel` entities for a - `InferenceService`. This path contains a `GET` and `POST` operation to perform the list and - create tasks, respectively. + The REST endpoint/path used to list and create zero or more `ServeModel` entities for a `InferenceService`. This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively. get: tags: - ModelRegistryService parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' - - - $ref: '#/components/parameters/pageSize' - - - $ref: '#/components/parameters/orderBy' - - - $ref: '#/components/parameters/sortOrder' - - - $ref: '#/components/parameters/nextPageToken' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" + - $ref: "#/components/parameters/pageSize" + - $ref: "#/components/parameters/orderBy" + - $ref: "#/components/parameters/sortOrder" + - $ref: "#/components/parameters/nextPageToken" responses: - '200': - $ref: '#/components/responses/ServeModelListResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ServeModelListResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getInferenceServiceServes summary: List All InferenceService's ServeModel actions description: Gets a list of all `ServeModel` entities for the `InferenceService`. @@ -876,83 +786,78 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ServeModelCreate' + $ref: "#/components/schemas/ServeModelCreate" required: true tags: - ModelRegistryService responses: - '201': - $ref: '#/components/responses/ServeModelResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "201": + $ref: "#/components/responses/ServeModelResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: createInferenceServiceServe summary: Create a ServeModel action in a InferenceService description: Creates a new instance of a `ServeModel` associated with `InferenceService`. parameters: - - - name: inferenceserviceId + - name: inferenceserviceId description: A unique identifier for a `InferenceService`. schema: type: string in: path required: true - '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/model': + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/model": summary: Path used to manage a `RegisteredModel` associated with an `InferenceService`. description: >- - The REST endpoint/path used to list the `RegisteredModel` entity for an `InferenceService`. This - path contains a `GET` operation to perform the get task. + The REST endpoint/path used to list the `RegisteredModel` entity for an `InferenceService`. This path contains a `GET` operation to perform the get task. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/RegisteredModelResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/RegisteredModelResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getInferenceServiceModel summary: Get InferenceService's RegisteredModel description: Gets the `RegisteredModel` entity for the `InferenceService`. parameters: - - - name: inferenceserviceId + - name: inferenceserviceId description: A unique identifier for a `InferenceService`. schema: type: string in: path required: true - '/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/version': + "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}/version": summary: Path used to get the current `ModelVersion` associated with an `InferenceService`. description: >- - The REST endpoint/path used to get the current `ModelVersion` entity for a `InferenceService`. - This path contains a `GET` operation to perform the get task. + The REST endpoint/path used to get the current `ModelVersion` entity for a `InferenceService`. This path contains a `GET` operation to perform the get task. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ModelVersionResponse' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelVersionResponse" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: getInferenceServiceVersion summary: Get InferenceService's ModelVersion description: Gets the `ModelVersion` entity for the `InferenceService`. parameters: - - - name: inferenceserviceId + - name: inferenceserviceId description: A unique identifier for a `InferenceService`. schema: type: string @@ -961,52 +866,48 @@ paths: /api/model_registry/v1alpha1/model_version: summary: Path used to search for a modelversion. description: >- - The REST endpoint/path used to search for a `ModelVersion` entity. This path contains a `GET` - operation to perform the find task. + The REST endpoint/path used to search for a `ModelVersion` entity. This path contains a `GET` operation to perform the find task. get: tags: - ModelRegistryService responses: - '200': - $ref: '#/components/responses/ModelVersionResponse' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '404': - $ref: '#/components/responses/NotFound' - '500': - $ref: '#/components/responses/InternalServerError' + "200": + $ref: "#/components/responses/ModelVersionResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + "404": + $ref: "#/components/responses/NotFound" + "500": + $ref: "#/components/responses/InternalServerError" operationId: findModelVersion summary: Get a ModelVersion that matches search parameters. description: Gets the details of a single instance of a `ModelVersion` that matches search parameters. parameters: - - - $ref: '#/components/parameters/name' - - - $ref: '#/components/parameters/externalID' - - - $ref: '#/components/parameters/parentResourceID' + - $ref: "#/components/parameters/name" + - $ref: "#/components/parameters/externalID" + - $ref: "#/components/parameters/parentResourceID" components: schemas: ArtifactState: - description: |4- - - PENDING: A state indicating that the artifact may exist. - - LIVE: A state indicating that the artifact should exist, unless something - external to the system deletes it. - - MARKED_FOR_DELETION: A state indicating that the artifact should be deleted. - - DELETED: A state indicating that the artifact has been deleted. - - ABANDONED: A state indicating that the artifact has been abandoned, which may be - due to a failed or cancelled execution. - - REFERENCE: A state indicating that the artifact is a reference artifact. At - execution start time, the orchestrator produces an output artifact for - each output key with state PENDING. However, for an intermediate - artifact, this first artifact's state will be REFERENCE. Intermediate - artifacts emitted during a component's execution will copy the REFERENCE - artifact's attributes. At the end of an execution, the artifact state - should remain REFERENCE instead of being changed to LIVE. - - See also: ml-metadata Artifact.State + description: |2- + - PENDING: A state indicating that the artifact may exist. + - LIVE: A state indicating that the artifact should exist, unless something + external to the system deletes it. + - MARKED_FOR_DELETION: A state indicating that the artifact should be deleted. + - DELETED: A state indicating that the artifact has been deleted. + - ABANDONED: A state indicating that the artifact has been abandoned, which may be + due to a failed or cancelled execution. + - REFERENCE: A state indicating that the artifact is a reference artifact. At + execution start time, the orchestrator produces an output artifact for + each output key with state PENDING. However, for an intermediate + artifact, this first artifact's state will be REFERENCE. Intermediate + artifacts emitted during a component's execution will copy the REFERENCE + artifact's attributes. At the end of an execution, the artifact state + should remain REFERENCE instead of being changed to LIVE. + + See also: ml-metadata Artifact.State default: UNKNOWN enum: - UNKNOWN @@ -1055,7 +956,7 @@ components: different from CACHED in that a CANCELED execution will not have any event associated with it. It is different from FAILED in that there is no unexpected error happened and it is regarded as a normal state. - + See also: ml-metadata Execution.State default: UNKNOWN enum: @@ -1071,12 +972,9 @@ components: description: An ML model artifact. type: object allOf: - - - $ref: '#/components/schemas/BaseArtifact' - - - $ref: '#/components/schemas/ModelArtifactCreate' - - - type: object + - $ref: "#/components/schemas/BaseArtifact" + - $ref: "#/components/schemas/ModelArtifactCreate" + - type: object properties: artifactType: type: string @@ -1084,75 +982,59 @@ components: RegisteredModel: description: A registered model in model registry. A registered model has ModelVersion children. allOf: - - - $ref: '#/components/schemas/BaseResource' - - - type: object - - - $ref: '#/components/schemas/RegisteredModelCreate' + - $ref: "#/components/schemas/BaseResource" + - type: object + - $ref: "#/components/schemas/RegisteredModelCreate" ModelVersionList: description: List of ModelVersion entities. type: object allOf: - - - type: object + - type: object properties: items: description: Array of `ModelVersion` entities. type: array items: - $ref: '#/components/schemas/ModelVersion' - - - $ref: '#/components/schemas/BaseResourceList' + $ref: "#/components/schemas/ModelVersion" + - $ref: "#/components/schemas/BaseResourceList" ModelArtifactList: description: List of ModelArtifact entities. type: object allOf: - - - type: object + - type: object properties: items: description: Array of `ModelArtifact` entities. type: array items: - $ref: '#/components/schemas/ModelArtifact' - - - $ref: '#/components/schemas/BaseResourceList' + $ref: "#/components/schemas/ModelArtifact" + - $ref: "#/components/schemas/BaseResourceList" RegisteredModelCreate: description: A registered model in model registry. A registered model has ModelVersion children. allOf: - - - type: object - - - $ref: '#/components/schemas/BaseResourceCreate' - - - $ref: '#/components/schemas/RegisteredModelUpdate' + - type: object + - $ref: "#/components/schemas/BaseResourceCreate" + - $ref: "#/components/schemas/RegisteredModelUpdate" RegisteredModelUpdate: description: A registered model in model registry. A registered model has ModelVersion children. allOf: - - - $ref: '#/components/schemas/BaseResourceUpdate' - - - type: object + - $ref: "#/components/schemas/BaseResourceUpdate" + - type: object properties: state: - $ref: '#/components/schemas/RegisteredModelState' + $ref: "#/components/schemas/RegisteredModelState" ModelVersion: description: Represents a ModelVersion belonging to a RegisteredModel. allOf: - - - $ref: '#/components/schemas/ModelVersionCreate' - - - $ref: '#/components/schemas/BaseResource' + - $ref: "#/components/schemas/ModelVersionCreate" + - $ref: "#/components/schemas/BaseResource" ModelVersionCreate: description: Represents a ModelVersion belonging to a RegisteredModel. required: - registeredModelID allOf: - - - $ref: '#/components/schemas/BaseResourceCreate' - - - $ref: '#/components/schemas/ModelVersionUpdate' + - $ref: "#/components/schemas/BaseResourceCreate" + - $ref: "#/components/schemas/ModelVersionUpdate" properties: registeredModelID: description: ID of the `RegisteredModel` to which this version belongs. @@ -1160,28 +1042,22 @@ components: ModelVersionUpdate: description: Represents a ModelVersion belonging to a RegisteredModel. allOf: - - - $ref: '#/components/schemas/BaseResourceUpdate' - - - type: object + - $ref: "#/components/schemas/BaseResourceUpdate" + - type: object properties: state: - $ref: '#/components/schemas/ModelVersionState' + $ref: "#/components/schemas/ModelVersionState" author: description: Name of the author. type: string BaseArtifactCreate: allOf: - - - $ref: '#/components/schemas/BaseArtifactUpdate' - - - $ref: '#/components/schemas/BaseResourceCreate' + - $ref: "#/components/schemas/BaseArtifactUpdate" + - $ref: "#/components/schemas/BaseResourceCreate" BaseArtifactUpdate: allOf: - - - $ref: '#/components/schemas/BaseResourceUpdate' - - - type: object + - $ref: "#/components/schemas/BaseResourceUpdate" + - type: object properties: uri: description: |- @@ -1189,47 +1065,33 @@ components: May be empty if there is no physical artifact. type: string state: - $ref: '#/components/schemas/ArtifactState' + $ref: "#/components/schemas/ArtifactState" BaseExecution: allOf: - - - $ref: '#/components/schemas/BaseExecutionCreate' - - - type: object - - - $ref: '#/components/schemas/BaseResource' + - $ref: "#/components/schemas/BaseExecutionCreate" + - type: object + - $ref: "#/components/schemas/BaseResource" BaseExecutionCreate: allOf: - - - $ref: '#/components/schemas/BaseExecutionUpdate' - - - type: object - - - $ref: '#/components/schemas/BaseResourceCreate' + - $ref: "#/components/schemas/BaseExecutionUpdate" + - type: object + - $ref: "#/components/schemas/BaseResourceCreate" BaseExecutionUpdate: type: object allOf: - - - type: object + - type: object properties: lastKnownState: - $ref: '#/components/schemas/ExecutionState' - - - $ref: '#/components/schemas/BaseResourceUpdate' + $ref: "#/components/schemas/ExecutionState" + - $ref: "#/components/schemas/BaseResourceUpdate" MetadataValue: oneOf: - - - $ref: '#/components/schemas/MetadataIntValue' - - - $ref: '#/components/schemas/MetadataDoubleValue' - - - $ref: '#/components/schemas/MetadataStringValue' - - - $ref: '#/components/schemas/MetadataStructValue' - - - $ref: '#/components/schemas/MetadataProtoValue' - - - $ref: '#/components/schemas/MetadataBoolValue' + - $ref: "#/components/schemas/MetadataIntValue" + - $ref: "#/components/schemas/MetadataDoubleValue" + - $ref: "#/components/schemas/MetadataStringValue" + - $ref: "#/components/schemas/MetadataStructValue" + - $ref: "#/components/schemas/MetadataProtoValue" + - $ref: "#/components/schemas/MetadataBoolValue" description: A value in properties. MetadataIntValue: description: An integer (int64) property value. @@ -1276,10 +1138,8 @@ components: type: boolean BaseResource: allOf: - - - $ref: '#/components/schemas/BaseResourceCreate' - - - type: object + - $ref: "#/components/schemas/BaseResourceCreate" + - type: object properties: id: format: int64 @@ -1300,10 +1160,8 @@ components: readOnly: true BaseResourceCreate: allOf: - - - $ref: '#/components/schemas/BaseResourceUpdate' - - - type: object + - $ref: "#/components/schemas/BaseResourceUpdate" + - type: object properties: name: description: |- @@ -1318,7 +1176,7 @@ components: description: User provided custom properties which are not defined by its type. type: object additionalProperties: - $ref: '#/components/schemas/MetadataValue' + $ref: "#/components/schemas/MetadataValue" description: description: |- An optional description about the resource. @@ -1350,23 +1208,19 @@ components: description: A list of Artifact entities. type: object allOf: - - - type: object + - type: object properties: items: description: Array of `Artifact` entities. type: array items: - $ref: '#/components/schemas/Artifact' - - - $ref: '#/components/schemas/BaseResourceList' + $ref: "#/components/schemas/Artifact" + - $ref: "#/components/schemas/BaseResourceList" ModelArtifactUpdate: description: An ML model artifact. allOf: - - - $ref: '#/components/schemas/BaseArtifactUpdate' - - - type: object + - $ref: "#/components/schemas/BaseArtifactUpdate" + - type: object properties: modelFormatName: description: Name of the model format. @@ -1387,10 +1241,8 @@ components: description: An ML model artifact. type: object allOf: - - - $ref: '#/components/schemas/BaseArtifactCreate' - - - $ref: '#/components/schemas/ModelArtifactUpdate' + - $ref: "#/components/schemas/BaseArtifactCreate" + - $ref: "#/components/schemas/ModelArtifactUpdate" Error: description: Error code and message. required: @@ -1419,21 +1271,17 @@ components: type: string Artifact: oneOf: - - - $ref: '#/components/schemas/ModelArtifact' + - $ref: "#/components/schemas/ModelArtifact" discriminator: propertyName: artifactType mapping: - model-artifact: '#/components/schemas/ModelArtifact' + model-artifact: "#/components/schemas/ModelArtifact" description: A metadata Artifact Entity. BaseArtifact: allOf: - - - $ref: '#/components/schemas/BaseArtifactCreate' - - - $ref: '#/components/schemas/BaseResource' - - - required: + - $ref: "#/components/schemas/BaseArtifactCreate" + - $ref: "#/components/schemas/BaseResource" + - required: - artifactType type: object properties: @@ -1443,115 +1291,91 @@ components: description: List of ServingEnvironments. type: object allOf: - - - type: object + - type: object properties: items: - description: '' + description: "" type: array items: - $ref: '#/components/schemas/ServingEnvironment' + $ref: "#/components/schemas/ServingEnvironment" readOnly: false - - - $ref: '#/components/schemas/BaseResourceList' + - $ref: "#/components/schemas/BaseResourceList" RegisteredModelList: description: List of RegisteredModels. type: object allOf: - - - type: object + - type: object properties: items: - description: '' + description: "" type: array items: - $ref: '#/components/schemas/RegisteredModel' + $ref: "#/components/schemas/RegisteredModel" readOnly: false - - - $ref: '#/components/schemas/BaseResourceList' + - $ref: "#/components/schemas/BaseResourceList" ServingEnvironment: description: A Model Serving environment for serving `RegisteredModels`. allOf: - - - $ref: '#/components/schemas/BaseResource' - - - type: object - - - $ref: '#/components/schemas/ServingEnvironmentCreate' + - $ref: "#/components/schemas/BaseResource" + - type: object + - $ref: "#/components/schemas/ServingEnvironmentCreate" ServingEnvironmentUpdate: description: A Model Serving environment for serving `RegisteredModels`. allOf: - - - $ref: '#/components/schemas/BaseResourceUpdate' + - $ref: "#/components/schemas/BaseResourceUpdate" ServingEnvironmentCreate: description: A Model Serving environment for serving `RegisteredModels`. allOf: - - - type: object - - - $ref: '#/components/schemas/BaseResourceCreate' - - - $ref: '#/components/schemas/ServingEnvironmentUpdate' + - type: object + - $ref: "#/components/schemas/BaseResourceCreate" + - $ref: "#/components/schemas/ServingEnvironmentUpdate" InferenceService: description: >- - An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` - from a `RegisteredModel` created by Model Serving. + An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` from a `RegisteredModel` created by Model Serving. allOf: - - - $ref: '#/components/schemas/BaseResource' - - - $ref: '#/components/schemas/InferenceServiceCreate' + - $ref: "#/components/schemas/BaseResource" + - $ref: "#/components/schemas/InferenceServiceCreate" InferenceServiceList: description: List of InferenceServices. type: object allOf: - - - type: object + - type: object properties: items: - description: '' + description: "" type: array items: - $ref: '#/components/schemas/InferenceService' + $ref: "#/components/schemas/InferenceService" readOnly: false - - - $ref: '#/components/schemas/BaseResourceList' + - $ref: "#/components/schemas/BaseResourceList" ServeModelList: description: List of ServeModel entities. type: object allOf: - - - type: object + - type: object properties: items: description: Array of `ModelArtifact` entities. type: array items: - $ref: '#/components/schemas/ServeModel' - - - $ref: '#/components/schemas/BaseResourceList' + $ref: "#/components/schemas/ServeModel" + - $ref: "#/components/schemas/BaseResourceList" ServeModel: description: An ML model serving action. type: object allOf: - - - $ref: '#/components/schemas/BaseExecution' - - - $ref: '#/components/schemas/ServeModelCreate' + - $ref: "#/components/schemas/BaseExecution" + - $ref: "#/components/schemas/ServeModelCreate" ServeModelUpdate: description: An ML model serving action. allOf: - - - $ref: '#/components/schemas/BaseExecutionUpdate' + - $ref: "#/components/schemas/BaseExecutionUpdate" ServeModelCreate: description: An ML model serving action. allOf: - - - $ref: '#/components/schemas/BaseExecutionCreate' - - - $ref: '#/components/schemas/ServeModelUpdate' - - - required: + - $ref: "#/components/schemas/BaseExecutionCreate" + - $ref: "#/components/schemas/ServeModelUpdate" + - required: - modelVersionId type: object properties: @@ -1560,35 +1384,27 @@ components: type: string InferenceServiceUpdate: description: >- - An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` - from a `RegisteredModel` created by Model Serving. + An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` from a `RegisteredModel` created by Model Serving. allOf: - - - $ref: '#/components/schemas/BaseResourceUpdate' - - - type: object + - $ref: "#/components/schemas/BaseResourceUpdate" + - type: object properties: modelVersionId: description: >- - ID of the `ModelVersion` to serve. If it's unspecified, then the latest - `ModelVersion` by creation order will be served. + ID of the `ModelVersion` to serve. If it's unspecified, then the latest `ModelVersion` by creation order will be served. type: string runtime: description: Model runtime. type: string desiredState: - $ref: '#/components/schemas/InferenceServiceState' + $ref: "#/components/schemas/InferenceServiceState" InferenceServiceCreate: description: >- - An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` - from a `RegisteredModel` created by Model Serving. + An `InferenceService` entity in a `ServingEnvironment` represents a deployed `ModelVersion` from a `RegisteredModel` created by Model Serving. allOf: - - - $ref: '#/components/schemas/BaseResourceCreate' - - - $ref: '#/components/schemas/InferenceServiceUpdate' - - - required: + - $ref: "#/components/schemas/BaseResourceCreate" + - $ref: "#/components/schemas/InferenceServiceUpdate" + - required: - registeredModelId - servingEnvironmentId type: object @@ -1604,109 +1420,109 @@ components: content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: "#/components/schemas/Error" description: The specified resource was not found BadRequest: content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: "#/components/schemas/Error" description: Bad Request parameters Unauthorized: content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: "#/components/schemas/Error" description: Unauthorized InternalServerError: content: application/json: schema: - $ref: '#/components/schemas/Error' + $ref: "#/components/schemas/Error" description: Unexpected internal server error ModelArtifactListResponse: content: application/json: schema: - $ref: '#/components/schemas/ModelArtifactList' + $ref: "#/components/schemas/ModelArtifactList" description: A response containing a list of ModelArtifact entities. ModelArtifactResponse: content: application/json: schema: - $ref: '#/components/schemas/ModelArtifact' + $ref: "#/components/schemas/ModelArtifact" description: A response containing a `ModelArtifact` entity. ModelVersionListResponse: content: application/json: schema: - $ref: '#/components/schemas/ModelVersionList' + $ref: "#/components/schemas/ModelVersionList" description: A response containing a list of `ModelVersion` entities. ModelVersionResponse: content: application/json: schema: - $ref: '#/components/schemas/ModelVersion' + $ref: "#/components/schemas/ModelVersion" description: A response containing a `ModelVersion` entity. RegisteredModelListResponse: content: application/json: schema: - $ref: '#/components/schemas/RegisteredModelList' + $ref: "#/components/schemas/RegisteredModelList" description: A response containing a list of `RegisteredModel` entities. RegisteredModelResponse: content: application/json: schema: - $ref: '#/components/schemas/RegisteredModel' + $ref: "#/components/schemas/RegisteredModel" description: A response containing a `RegisteredModel` entity. ArtifactResponse: content: application/json: schema: - $ref: '#/components/schemas/Artifact' + $ref: "#/components/schemas/Artifact" description: A response containing an `Artifact` entity. ArtifactListResponse: content: application/json: schema: - $ref: '#/components/schemas/ArtifactList' + $ref: "#/components/schemas/ArtifactList" description: A response containing a list of `Artifact` entities. ServingEnvironmentListResponse: content: application/json: schema: - $ref: '#/components/schemas/ServingEnvironmentList' + $ref: "#/components/schemas/ServingEnvironmentList" description: A response containing a list of `ServingEnvironment` entities. ServingEnvironmentResponse: content: application/json: schema: - $ref: '#/components/schemas/ServingEnvironment' + $ref: "#/components/schemas/ServingEnvironment" description: A response containing a `ServingEnvironment` entity. InferenceServiceListResponse: content: application/json: schema: - $ref: '#/components/schemas/InferenceServiceList' + $ref: "#/components/schemas/InferenceServiceList" description: A response containing a list of `InferenceService` entities. InferenceServiceResponse: content: application/json: schema: - $ref: '#/components/schemas/InferenceService' + $ref: "#/components/schemas/InferenceService" description: A response containing a `InferenceService` entity. ServeModelListResponse: content: application/json: schema: - $ref: '#/components/schemas/ServeModelList' + $ref: "#/components/schemas/ServeModelList" description: A response containing a list of `ServeModel` entities. ServeModelResponse: content: application/json: schema: - $ref: '#/components/schemas/ServeModel' + $ref: "#/components/schemas/ServeModel" description: A response containing a `ServeModel` entity. parameters: id: @@ -1729,7 +1545,7 @@ components: externalID: examples: externalID: - value: '10' + value: "10" name: externalID description: External ID of entity to search. schema: @@ -1739,7 +1555,7 @@ components: parentResourceID: examples: parentResourceID: - value: '10' + value: "10" name: parentResourceID description: ID of the parent resource to use for search. schema: @@ -1749,7 +1565,7 @@ components: pageSize: examples: pageSize: - value: '100' + value: "100" name: pageSize description: Number of entities in each page. schema: @@ -1775,7 +1591,7 @@ components: name: orderBy description: Specifies the order by criteria for listing entities. schema: - $ref: '#/components/schemas/OrderByField' + $ref: "#/components/schemas/OrderByField" in: query required: false sortOrder: @@ -1785,9 +1601,9 @@ components: sortOrder: value: DESC name: sortOrder - description: 'Specifies the sort order for listing entities, defaults to ASC.' + description: "Specifies the sort order for listing entities, defaults to ASC." schema: - $ref: '#/components/schemas/SortOrder' + $ref: "#/components/schemas/SortOrder" in: query required: false securitySchemes: @@ -1797,9 +1613,7 @@ components: type: http description: Bearer JWT scheme security: - - - Bearer: [] + - Bearer: [] tags: - - - name: ModelRegistryService + - name: ModelRegistryService description: Model Registry Service REST API diff --git a/clients/python/src/model_registry/store/base.py b/clients/python/src/model_registry/store/base.py index ca381f8e..3482ee9e 100644 --- a/clients/python/src/model_registry/store/base.py +++ b/clients/python/src/model_registry/store/base.py @@ -4,10 +4,9 @@ from ml_metadata.proto import Artifact, Context +# Union of all proto types. ProtoType = Union[Artifact, Context] -"""Union of all proto types. """ +# Union of all scalar types. +# +# Those types are easy to map to and from proto types, and can also be queried in MLMD. ScalarType = Union[str, int, float, bool] -"""Union of all scalar types. - -Those types are easy to map to and from proto types, and can also be queried in MLMD. -""" diff --git a/cmd/proxy.go b/cmd/proxy.go index 3bbc8adb..f3ef6793 100644 --- a/cmd/proxy.go +++ b/cmd/proxy.go @@ -22,7 +22,7 @@ var ( Short: "Starts the ml-metadata go OpenAPI proxy", Long: `This command launches the ml-metadata go OpenAPI proxy server. -The server connects to a mlmd CPP server. It supports options to customize the +The server connects to a mlmd CPP server. It supports options to customize the hostname and port where it listens.'`, RunE: runProxyServer, } diff --git a/cmd/root.go b/cmd/root.go index 31ca6ddf..a2ff45cd 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -19,14 +19,14 @@ var cfgFile string var rootCmd = &cobra.Command{ Use: "model-registry", Short: "A go server for ml-metadata", - Long: `The model-registry is a gRPC server that stores metadata -for ML applications. - -It's based on the ml-metadata project that provides a python client library -for ML applications to record metadata about metadata such as Artifacts, -Executions and Contexts. -This go server is an alternative to the CPP gRPC service provided by the -ml-metadata project. It's meant to provide extra features such as loading + Long: `The model-registry is a gRPC server that stores metadata +for ML applications. + +It's based on the ml-metadata project that provides a python client library +for ML applications to record metadata about metadata such as Artifacts, +Executions and Contexts. +This go server is an alternative to the CPP gRPC service provided by the +ml-metadata project. It's meant to provide extra features such as loading custom metadata libraries, exposing a higher level GraphQL API, RBAC, etc.`, // Uncomment the following line if your bare application // has an action associated with it: diff --git a/docker-compose-local.yaml b/docker-compose-local.yaml index cddf36f8..52b7601f 100644 --- a/docker-compose-local.yaml +++ b/docker-compose-local.yaml @@ -10,11 +10,11 @@ services: volumes: - ./test/config/ml-metadata:/tmp/shared model-registry: - build: + build: context: . dockerfile: Dockerfile command: ["proxy", "--mlmd-hostname", "localhost", "--mlmd-port", "9090"] container_name: model-registry network_mode: host - depends_on: - - mlmd-server \ No newline at end of file + depends_on: + - mlmd-server diff --git a/docker-compose.yaml b/docker-compose.yaml index 69822807..4f8e2d98 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -14,5 +14,5 @@ services: command: ["proxy", "--mlmd-hostname", "localhost", "--mlmd-port", "9090"] container_name: model-registry network_mode: host - depends_on: - - mlmd-server \ No newline at end of file + depends_on: + - mlmd-server diff --git a/docs/mr_go_library.md b/docs/mr_go_library.md index a0653bb3..1754eec6 100644 --- a/docs/mr_go_library.md +++ b/docs/mr_go_library.md @@ -142,4 +142,4 @@ allVersions, err := service.GetModelVersions(api.ListOptions{}, registeredModel. if err != nil { return fmt.Errorf("error retrieving model versions for model %s: %v", *registeredModel.Id, err) } -``` \ No newline at end of file +``` diff --git a/docs/remote_only_packaging_of_MLMD_Python_lib.md b/docs/remote_only_packaging_of_MLMD_Python_lib.md index 8d4abde9..57bd0c65 100644 --- a/docs/remote_only_packaging_of_MLMD_Python_lib.md +++ b/docs/remote_only_packaging_of_MLMD_Python_lib.md @@ -4,7 +4,7 @@ Google’s ML Metadata (MLMD) is a project composed of a C++ server, and a Python client library. The server exposes a gRPC interface, and is only distributed for x86-64 architectures. -It is embedded in the client's wheel binary, providing an additional convenience [method for running the server locally (in memory)](https://www.tensorflow.org/tfx/guide/mlmd#metadata_storage_backends_and_store_connection_configuration), +It is embedded in the client's wheel binary, providing an additional convenience [method for running the server locally (in memory)](https://www.tensorflow.org/tfx/guide/mlmd#metadata_storage_backends_and_store_connection_configuration), whilst also making it [architecture specific](https://pypi.org/project/ml-metadata/1.14.0/#files). The [Model Registry project](https://docs.google.com/document/d/1G-pjdGaS2kLELsB5kYk_D4AmH-fTfnCnJOhJ8xENjx0/edit?usp=sharing) (MR) is built on top of MLMD. diff --git a/internal/server/openapi/.openapi-generator/VERSION b/internal/server/openapi/.openapi-generator/VERSION index 73a86b19..9fe9ff9d 100644 --- a/internal/server/openapi/.openapi-generator/VERSION +++ b/internal/server/openapi/.openapi-generator/VERSION @@ -1 +1 @@ -7.0.1 \ No newline at end of file +7.0.1 diff --git a/patches/type_asserts.patch b/patches/type_asserts.patch index 4784fdc3..8735b1c2 100644 --- a/patches/type_asserts.patch +++ b/patches/type_asserts.patch @@ -3,7 +3,7 @@ index 4318f15..2aba64a 100644 --- a/internal/server/openapi/type_asserts.go +++ b/internal/server/openapi/type_asserts.go @@ -18,15 +18,15 @@ import ( - + // AssertArtifactRequired checks if the required fields are not zero-ed func AssertArtifactRequired(obj model.Artifact) error { - elements := map[string]interface{}{ @@ -26,4 +26,3 @@ index 4318f15..2aba64a 100644 + // } return nil } - diff --git a/scripts/build_deploy.sh b/scripts/build_deploy.sh index 5f066110..df610c37 100755 --- a/scripts/build_deploy.sh +++ b/scripts/build_deploy.sh @@ -69,4 +69,4 @@ if [[ "${PUSH_IMAGE,,}" == "true" ]]; then image/push else echo "Skip container image push." -fi \ No newline at end of file +fi diff --git a/scripts/gen_type_asserts.sh b/scripts/gen_type_asserts.sh index b49f650a..27808c3a 100755 --- a/scripts/gen_type_asserts.sh +++ b/scripts/gen_type_asserts.sh @@ -21,7 +21,7 @@ INITIAL_CONTENT=$(cat < Date: Wed, 7 Feb 2024 18:43:08 +0100 Subject: [PATCH 234/254] Remove lint from the build/odh cmd (#293) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c4a720bc..be478903 100644 --- a/Makefile +++ b/Makefile @@ -152,7 +152,7 @@ build: gen vet lint go build .PHONY: build/odh -build/odh: vet lint +build/odh: vet go build .PHONY: gen From 351a7f2fa2428942ab430c03c30d130d9cd0fa78 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Thu, 8 Feb 2024 10:06:15 -0800 Subject: [PATCH 235/254] chore: fix documentation info section version in rest api, fixes RHOAIENG-2889 (#296) --- api/openapi/model-registry.yaml | 2 +- pkg/openapi/api_model_registry_service.go | 2 +- pkg/openapi/client.go | 4 ++-- pkg/openapi/configuration.go | 2 +- pkg/openapi/model_artifact.go | 2 +- pkg/openapi/model_artifact_list.go | 2 +- pkg/openapi/model_artifact_state.go | 2 +- pkg/openapi/model_base_artifact.go | 2 +- pkg/openapi/model_base_artifact_create.go | 2 +- pkg/openapi/model_base_artifact_update.go | 2 +- pkg/openapi/model_base_execution.go | 2 +- pkg/openapi/model_base_execution_create.go | 2 +- pkg/openapi/model_base_execution_update.go | 2 +- pkg/openapi/model_base_resource.go | 2 +- pkg/openapi/model_base_resource_create.go | 2 +- pkg/openapi/model_base_resource_list.go | 2 +- pkg/openapi/model_base_resource_update.go | 2 +- pkg/openapi/model_error.go | 2 +- pkg/openapi/model_execution_state.go | 2 +- pkg/openapi/model_inference_service.go | 2 +- pkg/openapi/model_inference_service_create.go | 2 +- pkg/openapi/model_inference_service_list.go | 2 +- pkg/openapi/model_inference_service_state.go | 2 +- pkg/openapi/model_inference_service_update.go | 2 +- pkg/openapi/model_metadata_bool_value.go | 2 +- pkg/openapi/model_metadata_double_value.go | 2 +- pkg/openapi/model_metadata_int_value.go | 2 +- pkg/openapi/model_metadata_proto_value.go | 2 +- pkg/openapi/model_metadata_string_value.go | 2 +- pkg/openapi/model_metadata_struct_value.go | 2 +- pkg/openapi/model_metadata_value.go | 2 +- pkg/openapi/model_model_artifact.go | 2 +- pkg/openapi/model_model_artifact_create.go | 2 +- pkg/openapi/model_model_artifact_list.go | 2 +- pkg/openapi/model_model_artifact_update.go | 2 +- pkg/openapi/model_model_version.go | 2 +- pkg/openapi/model_model_version_create.go | 2 +- pkg/openapi/model_model_version_list.go | 2 +- pkg/openapi/model_model_version_state.go | 2 +- pkg/openapi/model_model_version_update.go | 2 +- pkg/openapi/model_order_by_field.go | 2 +- pkg/openapi/model_registered_model.go | 2 +- pkg/openapi/model_registered_model_create.go | 2 +- pkg/openapi/model_registered_model_list.go | 2 +- pkg/openapi/model_registered_model_state.go | 2 +- pkg/openapi/model_registered_model_update.go | 2 +- pkg/openapi/model_serve_model.go | 2 +- pkg/openapi/model_serve_model_create.go | 2 +- pkg/openapi/model_serve_model_list.go | 2 +- pkg/openapi/model_serve_model_update.go | 2 +- pkg/openapi/model_serving_environment.go | 2 +- pkg/openapi/model_serving_environment_create.go | 2 +- pkg/openapi/model_serving_environment_list.go | 2 +- pkg/openapi/model_serving_environment_update.go | 2 +- pkg/openapi/model_sort_order.go | 2 +- pkg/openapi/response.go | 2 +- pkg/openapi/utils.go | 2 +- 57 files changed, 58 insertions(+), 58 deletions(-) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index 72c0c6ad..d9c7ec08 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -1,7 +1,7 @@ openapi: 3.0.3 info: title: Model Registry REST API - version: 1.0.0 + version: v1alpha1 description: REST API for Model Registry to create and manage ML model metadata license: name: Apache 2.0 diff --git a/pkg/openapi/api_model_registry_service.go b/pkg/openapi/api_model_registry_service.go index 839c3106..91826b6e 100644 --- a/pkg/openapi/api_model_registry_service.go +++ b/pkg/openapi/api_model_registry_service.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/client.go b/pkg/openapi/client.go index 2379badf..d5438256 100644 --- a/pkg/openapi/client.go +++ b/pkg/openapi/client.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. @@ -40,7 +40,7 @@ var ( queryDescape = strings.NewReplacer("%5B", "[", "%5D", "]") ) -// APIClient manages communication with the Model Registry REST API API v1.0.0 +// APIClient manages communication with the Model Registry REST API API vv1alpha1 // In most cases there should be only one, shared, APIClient. type APIClient struct { cfg *Configuration diff --git a/pkg/openapi/configuration.go b/pkg/openapi/configuration.go index 66a6313c..7575d94d 100644 --- a/pkg/openapi/configuration.go +++ b/pkg/openapi/configuration.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_artifact.go b/pkg/openapi/model_artifact.go index af2f5b89..43b8f85b 100644 --- a/pkg/openapi/model_artifact.go +++ b/pkg/openapi/model_artifact.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_artifact_list.go b/pkg/openapi/model_artifact_list.go index 6eae5347..c970693f 100644 --- a/pkg/openapi/model_artifact_list.go +++ b/pkg/openapi/model_artifact_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_artifact_state.go b/pkg/openapi/model_artifact_state.go index d377ac0d..d703a613 100644 --- a/pkg/openapi/model_artifact_state.go +++ b/pkg/openapi/model_artifact_state.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_artifact.go b/pkg/openapi/model_base_artifact.go index 5e0fb9a1..ce0d21e1 100644 --- a/pkg/openapi/model_base_artifact.go +++ b/pkg/openapi/model_base_artifact.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_artifact_create.go b/pkg/openapi/model_base_artifact_create.go index 2f5f50da..dbd616eb 100644 --- a/pkg/openapi/model_base_artifact_create.go +++ b/pkg/openapi/model_base_artifact_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_artifact_update.go b/pkg/openapi/model_base_artifact_update.go index e24b2faf..dc89d09d 100644 --- a/pkg/openapi/model_base_artifact_update.go +++ b/pkg/openapi/model_base_artifact_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_execution.go b/pkg/openapi/model_base_execution.go index 45216b32..f650d51f 100644 --- a/pkg/openapi/model_base_execution.go +++ b/pkg/openapi/model_base_execution.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_execution_create.go b/pkg/openapi/model_base_execution_create.go index 91908887..4967ffa9 100644 --- a/pkg/openapi/model_base_execution_create.go +++ b/pkg/openapi/model_base_execution_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_execution_update.go b/pkg/openapi/model_base_execution_update.go index 44023c28..fdeaf485 100644 --- a/pkg/openapi/model_base_execution_update.go +++ b/pkg/openapi/model_base_execution_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_resource.go b/pkg/openapi/model_base_resource.go index 544d70fd..7890ecc8 100644 --- a/pkg/openapi/model_base_resource.go +++ b/pkg/openapi/model_base_resource.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_resource_create.go b/pkg/openapi/model_base_resource_create.go index 13e4e6d3..de4a731a 100644 --- a/pkg/openapi/model_base_resource_create.go +++ b/pkg/openapi/model_base_resource_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_resource_list.go b/pkg/openapi/model_base_resource_list.go index d438b687..a77926b9 100644 --- a/pkg/openapi/model_base_resource_list.go +++ b/pkg/openapi/model_base_resource_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_base_resource_update.go b/pkg/openapi/model_base_resource_update.go index dbf124c8..1bf46a46 100644 --- a/pkg/openapi/model_base_resource_update.go +++ b/pkg/openapi/model_base_resource_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_error.go b/pkg/openapi/model_error.go index 2ad91eaf..d7767fb9 100644 --- a/pkg/openapi/model_error.go +++ b/pkg/openapi/model_error.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_execution_state.go b/pkg/openapi/model_execution_state.go index 3cc5df20..e7852cb9 100644 --- a/pkg/openapi/model_execution_state.go +++ b/pkg/openapi/model_execution_state.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_inference_service.go b/pkg/openapi/model_inference_service.go index fdd1e4ea..731cb755 100644 --- a/pkg/openapi/model_inference_service.go +++ b/pkg/openapi/model_inference_service.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_inference_service_create.go b/pkg/openapi/model_inference_service_create.go index 8724b96f..01bdd97e 100644 --- a/pkg/openapi/model_inference_service_create.go +++ b/pkg/openapi/model_inference_service_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_inference_service_list.go b/pkg/openapi/model_inference_service_list.go index e016a5f8..2eb6b978 100644 --- a/pkg/openapi/model_inference_service_list.go +++ b/pkg/openapi/model_inference_service_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_inference_service_state.go b/pkg/openapi/model_inference_service_state.go index 84c39e0b..03ad022d 100644 --- a/pkg/openapi/model_inference_service_state.go +++ b/pkg/openapi/model_inference_service_state.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_inference_service_update.go b/pkg/openapi/model_inference_service_update.go index 9442f917..9a2c074b 100644 --- a/pkg/openapi/model_inference_service_update.go +++ b/pkg/openapi/model_inference_service_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_metadata_bool_value.go b/pkg/openapi/model_metadata_bool_value.go index 41cb261d..bb1c28a3 100644 --- a/pkg/openapi/model_metadata_bool_value.go +++ b/pkg/openapi/model_metadata_bool_value.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_metadata_double_value.go b/pkg/openapi/model_metadata_double_value.go index 5ab14b9c..d7fd2ef5 100644 --- a/pkg/openapi/model_metadata_double_value.go +++ b/pkg/openapi/model_metadata_double_value.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_metadata_int_value.go b/pkg/openapi/model_metadata_int_value.go index 367c6cf4..beb40354 100644 --- a/pkg/openapi/model_metadata_int_value.go +++ b/pkg/openapi/model_metadata_int_value.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_metadata_proto_value.go b/pkg/openapi/model_metadata_proto_value.go index 1c29ecd2..7b5c254b 100644 --- a/pkg/openapi/model_metadata_proto_value.go +++ b/pkg/openapi/model_metadata_proto_value.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_metadata_string_value.go b/pkg/openapi/model_metadata_string_value.go index bf40139a..b4457306 100644 --- a/pkg/openapi/model_metadata_string_value.go +++ b/pkg/openapi/model_metadata_string_value.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_metadata_struct_value.go b/pkg/openapi/model_metadata_struct_value.go index fc4255ca..7b97af73 100644 --- a/pkg/openapi/model_metadata_struct_value.go +++ b/pkg/openapi/model_metadata_struct_value.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_metadata_value.go b/pkg/openapi/model_metadata_value.go index 1ae1e9a0..0475c0b8 100644 --- a/pkg/openapi/model_metadata_value.go +++ b/pkg/openapi/model_metadata_value.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_artifact.go b/pkg/openapi/model_model_artifact.go index 56d708c9..1daa9934 100644 --- a/pkg/openapi/model_model_artifact.go +++ b/pkg/openapi/model_model_artifact.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_artifact_create.go b/pkg/openapi/model_model_artifact_create.go index b01bba78..353ac655 100644 --- a/pkg/openapi/model_model_artifact_create.go +++ b/pkg/openapi/model_model_artifact_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_artifact_list.go b/pkg/openapi/model_model_artifact_list.go index 93da4e4b..f31c95a1 100644 --- a/pkg/openapi/model_model_artifact_list.go +++ b/pkg/openapi/model_model_artifact_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_artifact_update.go b/pkg/openapi/model_model_artifact_update.go index e114c5f0..3d4e7d59 100644 --- a/pkg/openapi/model_model_artifact_update.go +++ b/pkg/openapi/model_model_artifact_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_version.go b/pkg/openapi/model_model_version.go index ee21bbbb..fd54c8ad 100644 --- a/pkg/openapi/model_model_version.go +++ b/pkg/openapi/model_model_version.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_version_create.go b/pkg/openapi/model_model_version_create.go index d825deeb..36c84624 100644 --- a/pkg/openapi/model_model_version_create.go +++ b/pkg/openapi/model_model_version_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_version_list.go b/pkg/openapi/model_model_version_list.go index 3a0a8d03..907df555 100644 --- a/pkg/openapi/model_model_version_list.go +++ b/pkg/openapi/model_model_version_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_version_state.go b/pkg/openapi/model_model_version_state.go index 802c7e60..09a408c4 100644 --- a/pkg/openapi/model_model_version_state.go +++ b/pkg/openapi/model_model_version_state.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_model_version_update.go b/pkg/openapi/model_model_version_update.go index 26ac9fe5..ed280546 100644 --- a/pkg/openapi/model_model_version_update.go +++ b/pkg/openapi/model_model_version_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_order_by_field.go b/pkg/openapi/model_order_by_field.go index 6c8c9e56..2b4ee75e 100644 --- a/pkg/openapi/model_order_by_field.go +++ b/pkg/openapi/model_order_by_field.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_registered_model.go b/pkg/openapi/model_registered_model.go index 9ed0d47d..f98f7f63 100644 --- a/pkg/openapi/model_registered_model.go +++ b/pkg/openapi/model_registered_model.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_registered_model_create.go b/pkg/openapi/model_registered_model_create.go index b03d8f64..eed1560d 100644 --- a/pkg/openapi/model_registered_model_create.go +++ b/pkg/openapi/model_registered_model_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_registered_model_list.go b/pkg/openapi/model_registered_model_list.go index 05892f0a..7c412830 100644 --- a/pkg/openapi/model_registered_model_list.go +++ b/pkg/openapi/model_registered_model_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_registered_model_state.go b/pkg/openapi/model_registered_model_state.go index 6ceb12dc..0e49818d 100644 --- a/pkg/openapi/model_registered_model_state.go +++ b/pkg/openapi/model_registered_model_state.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_registered_model_update.go b/pkg/openapi/model_registered_model_update.go index fc8f64d3..8f626d6a 100644 --- a/pkg/openapi/model_registered_model_update.go +++ b/pkg/openapi/model_registered_model_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serve_model.go b/pkg/openapi/model_serve_model.go index 950b43c1..27fb1149 100644 --- a/pkg/openapi/model_serve_model.go +++ b/pkg/openapi/model_serve_model.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serve_model_create.go b/pkg/openapi/model_serve_model_create.go index a740e77c..fe436a6d 100644 --- a/pkg/openapi/model_serve_model_create.go +++ b/pkg/openapi/model_serve_model_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serve_model_list.go b/pkg/openapi/model_serve_model_list.go index 2b3285b6..45a38088 100644 --- a/pkg/openapi/model_serve_model_list.go +++ b/pkg/openapi/model_serve_model_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serve_model_update.go b/pkg/openapi/model_serve_model_update.go index 74e2996b..b418c330 100644 --- a/pkg/openapi/model_serve_model_update.go +++ b/pkg/openapi/model_serve_model_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serving_environment.go b/pkg/openapi/model_serving_environment.go index 0d93a75b..4b45985c 100644 --- a/pkg/openapi/model_serving_environment.go +++ b/pkg/openapi/model_serving_environment.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serving_environment_create.go b/pkg/openapi/model_serving_environment_create.go index faff38de..e445e795 100644 --- a/pkg/openapi/model_serving_environment_create.go +++ b/pkg/openapi/model_serving_environment_create.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serving_environment_list.go b/pkg/openapi/model_serving_environment_list.go index 51c1c44b..f0eadef9 100644 --- a/pkg/openapi/model_serving_environment_list.go +++ b/pkg/openapi/model_serving_environment_list.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_serving_environment_update.go b/pkg/openapi/model_serving_environment_update.go index 3baaf117..f0818fe7 100644 --- a/pkg/openapi/model_serving_environment_update.go +++ b/pkg/openapi/model_serving_environment_update.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/model_sort_order.go b/pkg/openapi/model_sort_order.go index f2cdd0e3..6e1416b4 100644 --- a/pkg/openapi/model_sort_order.go +++ b/pkg/openapi/model_sort_order.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/response.go b/pkg/openapi/response.go index 7156934b..1d5cbaf7 100644 --- a/pkg/openapi/response.go +++ b/pkg/openapi/response.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. diff --git a/pkg/openapi/utils.go b/pkg/openapi/utils.go index 98fec2c7..2ccc6542 100644 --- a/pkg/openapi/utils.go +++ b/pkg/openapi/utils.go @@ -3,7 +3,7 @@ Model Registry REST API REST API for Model Registry to create and manage ML model metadata -API version: 1.0.0 +API version: v1alpha1 */ // Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. From 83e2535d09924c497ef602de6124203efe588107 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Mon, 5 Feb 2024 12:14:54 -0300 Subject: [PATCH 236/254] rename model artifact state mapping function Signed-off-by: Isabella Basso do Amaral --- .../generated/mlmd_openapi_converter.gen.go | 2 +- .../generated/openapi_mlmd_converter.gen.go | 2 +- .../converter/mlmd_converter_util_test.go | 12 ++++---- internal/converter/mlmd_openapi_converter.go | 2 +- .../converter/mlmd_openapi_converter_util.go | 2 +- internal/converter/openapi_mlmd_converter.go | 2 +- .../converter/openapi_mlmd_converter_util.go | 28 ++++++++++--------- 7 files changed, 26 insertions(+), 24 deletions(-) diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index 0be2c2a5..6ec760ee 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -62,7 +62,7 @@ func (c *MLMDToOpenAPIConverterImpl) ConvertModelArtifact(source *proto.Artifact pString2 = &xstring2 } openapiModelArtifact.Uri = pString2 - openapiModelArtifact.State = converter.MapMLMDModelArtifactState((*source).State) + openapiModelArtifact.State = converter.MapMLMDArtifactState((*source).State) openapiModelArtifact.Name = converter.MapNameFromOwned((*source).Name) openapiModelArtifact.Id = converter.Int64ToString((*source).Id) openapiModelArtifact.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) diff --git a/internal/converter/generated/openapi_mlmd_converter.gen.go b/internal/converter/generated/openapi_mlmd_converter.gen.go index f7cd116e..13116a54 100755 --- a/internal/converter/generated/openapi_mlmd_converter.gen.go +++ b/internal/converter/generated/openapi_mlmd_converter.gen.go @@ -111,7 +111,7 @@ func (c *OpenAPIToMLMDConverterImpl) ConvertModelArtifact(source *converter.Open if (*source).Model != nil { pOpenapiArtifactState = (*source).Model.State } - pProtoArtifact_State, err := converter.MapOpenAPIModelArtifactState(pOpenapiArtifactState) + pProtoArtifact_State, err := converter.MapOpenAPIArtifactState(pOpenapiArtifactState) if err != nil { return nil, fmt.Errorf("error setting field State: %w", err) } diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index d2f063c0..9b52bfa1 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -323,15 +323,15 @@ func TestMapModelArtifactName(t *testing.T) { assertion.Regexp(".*:v1", *name) } -func TestMapOpenAPIModelArtifactState(t *testing.T) { +func TestMapOpenAPIArtifactState(t *testing.T) { assertion := setup(t) - state, err := MapOpenAPIModelArtifactState(of(openapi.ARTIFACTSTATE_LIVE)) + state, err := MapOpenAPIArtifactState(of(openapi.ARTIFACTSTATE_LIVE)) assertion.Nil(err) assertion.NotNil(state) assertion.Equal(string(openapi.ARTIFACTSTATE_LIVE), state.String()) - state, err = MapOpenAPIModelArtifactState(nil) + state, err = MapOpenAPIArtifactState(nil) assertion.Nil(err) assertion.Nil(state) } @@ -530,14 +530,14 @@ func TestMapArtifactType(t *testing.T) { assertion.Equal("", artifactType) } -func TestMapMLMDModelArtifactState(t *testing.T) { +func TestMapMLMDArtifactState(t *testing.T) { assertion := setup(t) - artifactState := MapMLMDModelArtifactState(proto.Artifact_LIVE.Enum()) + artifactState := MapMLMDArtifactState(proto.Artifact_LIVE.Enum()) assertion.NotNil(artifactState) assertion.Equal("LIVE", string(*artifactState)) - artifactState = MapMLMDModelArtifactState(nil) + artifactState = MapMLMDArtifactState(nil) assertion.Nil(artifactState) } diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index dc28490a..8bfa3e53 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -26,7 +26,7 @@ type MLMDToOpenAPIConverter interface { // goverter:map Name | MapNameFromOwned // goverter:map . ArtifactType | MapArtifactType - // goverter:map State | MapMLMDModelArtifactState + // goverter:map State | MapMLMDArtifactState // goverter:map Properties Description | MapDescription // goverter:map Properties ModelFormatName | MapModelArtifactFormatName // goverter:map Properties ModelFormatVersion | MapModelArtifactFormatVersion diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 71f0a0b4..67f444dc 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -116,7 +116,7 @@ func MapInferenceServiceDesiredState(properties map[string]*proto.Value) *openap return (*openapi.InferenceServiceState)(&str) } -func MapMLMDModelArtifactState(source *proto.Artifact_State) *openapi.ArtifactState { +func MapMLMDArtifactState(source *proto.Artifact_State) (st *openapi.ArtifactState) { if source == nil { return nil } diff --git a/internal/converter/openapi_mlmd_converter.go b/internal/converter/openapi_mlmd_converter.go index 5d58c3da..c625e5a7 100644 --- a/internal/converter/openapi_mlmd_converter.go +++ b/internal/converter/openapi_mlmd_converter.go @@ -45,7 +45,7 @@ type OpenAPIToMLMDConverter interface { // goverter:map . Name | MapModelArtifactName // goverter:map Model Type | MapModelArtifactType // goverter:map Model Properties | MapModelArtifactProperties - // goverter:map Model.State State | MapOpenAPIModelArtifactState + // goverter:map Model.State State | MapOpenAPIArtifactState // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch ConvertModelArtifact(source *OpenAPIModelWrapper[openapi.ModelArtifact]) (*proto.Artifact, error) diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index 78bbb504..f42ff1d0 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -203,6 +203,21 @@ func MapModelVersionName(source *OpenAPIModelWrapper[openapi.ModelVersion]) *str return of(PrefixWhenOwned(source.ParentResourceId, *(*source).Model.Name)) } +// ARTIFACT + +func MapOpenAPIArtifactState(source *openapi.ArtifactState) (*proto.Artifact_State, error) { + if source == nil { + return nil, nil + } + + val, ok := proto.Artifact_State_value[string(*source)] + if !ok { + return nil, fmt.Errorf("invalid artifact state: %s", string(*source)) + } + + return (*proto.Artifact_State)(&val), nil +} + // MODEL ARTIFACT // MapModelArtifactProperties maps ModelArtifact fields to specific MLMD properties @@ -274,19 +289,6 @@ func MapModelArtifactName(source *OpenAPIModelWrapper[openapi.ModelArtifact]) *s return of(PrefixWhenOwned(source.ParentResourceId, artifactName)) } -func MapOpenAPIModelArtifactState(source *openapi.ArtifactState) (*proto.Artifact_State, error) { - if source == nil { - return nil, nil - } - - val, ok := proto.Artifact_State_value[string(*source)] - if !ok { - return nil, fmt.Errorf("invalid artifact state: %s", string(*source)) - } - - return (*proto.Artifact_State)(&val), nil -} - // SERVING ENVIRONMENT // MapServingEnvironmentType return ServingEnvironment corresponding MLMD context type From 3b0d790247f75cee0efaaac7217277b44ee2c9b2 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Mon, 5 Feb 2024 12:14:57 -0300 Subject: [PATCH 237/254] define OpenAPIModel as type constraint interface Signed-off-by: Isabella Basso do Amaral --- internal/converter/openapi_converter_util.go | 17 ++++++++--------- internal/converter/openapi_mlmd_converter.go | 7 +------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/internal/converter/openapi_converter_util.go b/internal/converter/openapi_converter_util.go index c82bda4a..c1bd6c8c 100644 --- a/internal/converter/openapi_converter_util.go +++ b/internal/converter/openapi_converter_util.go @@ -2,25 +2,24 @@ package converter import "github.com/opendatahub-io/model-registry/pkg/openapi" -type OpenapiUpdateWrapper[ - M openapi.RegisteredModel | +type OpenAPIModel interface { + openapi.RegisteredModel | openapi.ModelVersion | openapi.ModelArtifact | openapi.ServingEnvironment | openapi.InferenceService | - openapi.ServeModel, + openapi.ServeModel +} + +type OpenapiUpdateWrapper[ + M OpenAPIModel, ] struct { Existing *M Update *M } func NewOpenapiUpdateWrapper[ - M openapi.RegisteredModel | - openapi.ModelVersion | - openapi.ModelArtifact | - openapi.ServingEnvironment | - openapi.InferenceService | - openapi.ServeModel, + M OpenAPIModel, ](existing *M, update *M) OpenapiUpdateWrapper[M] { return OpenapiUpdateWrapper[M]{ Existing: existing, diff --git a/internal/converter/openapi_mlmd_converter.go b/internal/converter/openapi_mlmd_converter.go index c625e5a7..0652d06d 100644 --- a/internal/converter/openapi_mlmd_converter.go +++ b/internal/converter/openapi_mlmd_converter.go @@ -6,12 +6,7 @@ import ( ) type OpenAPIModelWrapper[ - M openapi.RegisteredModel | - openapi.ModelVersion | - openapi.ModelArtifact | - openapi.ServingEnvironment | - openapi.InferenceService | - openapi.ServeModel, + M OpenAPIModel, ] struct { TypeId int64 Model *M From cf1345a77beebd8543cb97aec3d773a9521f1028 Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Thu, 8 Feb 2024 09:54:18 -0300 Subject: [PATCH 238/254] Makefile: add HTML output on test-cover This also simplifies the coverage generation command as many flags are implicit. Signed-off-by: Isabella Basso do Amaral --- .gitignore | 2 +- Makefile | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 08c515b9..d566e0a8 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,7 @@ model-registry metadata.sqlite.db vendor -coverage.txt +coverage.* # Robot Framework files log.html diff --git a/Makefile b/Makefile index be478903..4e59ae60 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,8 @@ test-nocache: gen .PHONY: test-cover test-cover: gen - go test ./internal/... ./pkg/... -cover -count=1 -race -coverprofile=coverage.txt -covermode=atomic + go test ./internal/... ./pkg/... -coverprofile=coverage.txt + go tool cover -html=coverage.txt -o coverage.html .PHONY: run/proxy run/proxy: gen From 70eefeb1c667717d265d74b9f53c852d07bc39bc Mon Sep 17 00:00:00 2001 From: Isabella Basso do Amaral Date: Mon, 5 Feb 2024 12:14:57 -0300 Subject: [PATCH 239/254] add DocArtifact type Closes: #263 Signed-off-by: Isabella Basso do Amaral --- api/openapi/model-registry.yaml | 15 +- internal/constants/constants.go | 1 + .../generated/mlmd_openapi_converter.gen.go | 36 ++ .../generated/openapi_converter.gen.go | 5 + .../generated/openapi_mlmd_converter.gen.go | 64 +++ .../converter/mlmd_converter_util_test.go | 65 +++ internal/converter/mlmd_openapi_converter.go | 6 + .../converter/mlmd_openapi_converter_util.go | 15 +- internal/converter/openapi_converter.go | 6 + internal/converter/openapi_converter_test.go | 3 + internal/converter/openapi_converter_util.go | 8 + internal/converter/openapi_mlmd_converter.go | 8 + .../converter/openapi_mlmd_converter_util.go | 35 ++ internal/mapper/mapper.go | 90 ++-- internal/mapper/mapper_test.go | 46 +- internal/mlmdtypes/mlmdtypes.go | 17 + .../api_model_registry_service_service.go | 15 +- pkg/api/api.go | 8 + pkg/core/core.go | 219 ++++++--- pkg/core/core_test.go | 339 ++++++++++--- pkg/openapi/.openapi-generator/FILES | 1 + pkg/openapi/api_model_registry_service.go | 4 +- pkg/openapi/model_artifact.go | 40 ++ pkg/openapi/model_doc_artifact.go | 453 ++++++++++++++++++ 24 files changed, 1320 insertions(+), 179 deletions(-) create mode 100644 pkg/openapi/model_doc_artifact.go diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index d9c7ec08..c702eee7 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -367,8 +367,7 @@ paths: "500": $ref: "#/components/responses/InternalServerError" operationId: getModelVersionArtifacts - summary: List All ModelVersion's artifacts - description: Gets a list of all `Artifact` entities for the `ModelVersion`. + summary: List all artifacts associated with the `ModelVersion` post: requestBody: description: A new or existing `Artifact` to be associated with the `ModelVersion`. @@ -979,6 +978,16 @@ components: artifactType: type: string default: "model-artifact" + DocArtifact: + description: A document. + type: object + allOf: + - $ref: "#/components/schemas/BaseArtifact" + - type: object + properties: + artifactType: + type: string + default: "doc-artifact" RegisteredModel: description: A registered model in model registry. A registered model has ModelVersion children. allOf: @@ -1272,10 +1281,12 @@ components: Artifact: oneOf: - $ref: "#/components/schemas/ModelArtifact" + - $ref: "#/components/schemas/DocArtifact" discriminator: propertyName: artifactType mapping: model-artifact: "#/components/schemas/ModelArtifact" + doc-artifact: "#/components/schemas/DocArtifact" description: A metadata Artifact Entity. BaseArtifact: allOf: diff --git a/internal/constants/constants.go b/internal/constants/constants.go index d218d3fb..eabfa968 100644 --- a/internal/constants/constants.go +++ b/internal/constants/constants.go @@ -5,6 +5,7 @@ const ( RegisteredModelTypeName = "odh.RegisteredModel" ModelVersionTypeName = "odh.ModelVersion" ModelArtifactTypeName = "odh.ModelArtifact" + DocArtifactTypeName = "odh.DocArtifact" ServingEnvironmentTypeName = "odh.ServingEnvironment" InferenceServiceTypeName = "odh.InferenceService" ServeModelTypeName = "odh.ServeModel" diff --git a/internal/converter/generated/mlmd_openapi_converter.gen.go b/internal/converter/generated/mlmd_openapi_converter.gen.go index 6ec760ee..92ab100f 100755 --- a/internal/converter/generated/mlmd_openapi_converter.gen.go +++ b/internal/converter/generated/mlmd_openapi_converter.gen.go @@ -11,6 +11,42 @@ import ( type MLMDToOpenAPIConverterImpl struct{} +func (c *MLMDToOpenAPIConverterImpl) ConvertDocArtifact(source *proto.Artifact) (*openapi.DocArtifact, error) { + var pOpenapiDocArtifact *openapi.DocArtifact + if source != nil { + var openapiDocArtifact openapi.DocArtifact + mapStringOpenapiMetadataValue, err := converter.MapMLMDCustomProperties((*source).CustomProperties) + if err != nil { + return nil, err + } + openapiDocArtifact.CustomProperties = &mapStringOpenapiMetadataValue + openapiDocArtifact.Description = converter.MapDescription((*source).Properties) + var pString *string + if (*source).ExternalId != nil { + xstring := *(*source).ExternalId + pString = &xstring + } + openapiDocArtifact.ExternalID = pString + var pString2 *string + if (*source).Uri != nil { + xstring2 := *(*source).Uri + pString2 = &xstring2 + } + openapiDocArtifact.Uri = pString2 + openapiDocArtifact.State = converter.MapMLMDArtifactState((*source).State) + openapiDocArtifact.Name = converter.MapNameFromOwned((*source).Name) + openapiDocArtifact.Id = converter.Int64ToString((*source).Id) + openapiDocArtifact.CreateTimeSinceEpoch = converter.Int64ToString((*source).CreateTimeSinceEpoch) + openapiDocArtifact.LastUpdateTimeSinceEpoch = converter.Int64ToString((*source).LastUpdateTimeSinceEpoch) + xstring3, err := converter.MapArtifactType(source) + if err != nil { + return nil, fmt.Errorf("error setting field ArtifactType: %w", err) + } + openapiDocArtifact.ArtifactType = xstring3 + pOpenapiDocArtifact = &openapiDocArtifact + } + return pOpenapiDocArtifact, nil +} func (c *MLMDToOpenAPIConverterImpl) ConvertInferenceService(source *proto.Context) (*openapi.InferenceService, error) { var pOpenapiInferenceService *openapi.InferenceService if source != nil { diff --git a/internal/converter/generated/openapi_converter.gen.go b/internal/converter/generated/openapi_converter.gen.go index 2603742b..96cccad6 100755 --- a/internal/converter/generated/openapi_converter.gen.go +++ b/internal/converter/generated/openapi_converter.gen.go @@ -564,6 +564,11 @@ func (c *OpenAPIConverterImpl) ConvertServingEnvironmentUpdate(source *openapi.S } return pOpenapiServingEnvironment, nil } +func (c *OpenAPIConverterImpl) OverrideNotEditableForDocArtifact(source converter.OpenapiUpdateWrapper[openapi.DocArtifact]) (openapi.DocArtifact, error) { + openapiDocArtifact := converter.InitDocArtifactWithUpdate(source) + _ = source + return openapiDocArtifact, nil +} func (c *OpenAPIConverterImpl) OverrideNotEditableForInferenceService(source converter.OpenapiUpdateWrapper[openapi.InferenceService]) (openapi.InferenceService, error) { openapiInferenceService := converter.InitInferenceServiceWithUpdate(source) var pString *string diff --git a/internal/converter/generated/openapi_mlmd_converter.gen.go b/internal/converter/generated/openapi_mlmd_converter.gen.go index 13116a54..5badda5f 100755 --- a/internal/converter/generated/openapi_mlmd_converter.gen.go +++ b/internal/converter/generated/openapi_mlmd_converter.gen.go @@ -11,6 +11,70 @@ import ( type OpenAPIToMLMDConverterImpl struct{} +func (c *OpenAPIToMLMDConverterImpl) ConvertDocArtifact(source *converter.OpenAPIModelWrapper[openapi.DocArtifact]) (*proto.Artifact, error) { + var pProtoArtifact *proto.Artifact + if source != nil { + var protoArtifact proto.Artifact + var pString *string + if (*source).Model != nil { + pString = (*source).Model.Id + } + pInt64, err := converter.StringToInt64(pString) + if err != nil { + return nil, fmt.Errorf("error setting field Id: %w", err) + } + protoArtifact.Id = pInt64 + protoArtifact.Name = converter.MapDocArtifactName(source) + pInt642 := (*source).TypeId + protoArtifact.TypeId = &pInt642 + protoArtifact.Type = converter.MapDocArtifactType((*source).Model) + var pString2 *string + if (*source).Model != nil { + pString2 = (*source).Model.Uri + } + var pString3 *string + if pString2 != nil { + xstring := *pString2 + pString3 = &xstring + } + protoArtifact.Uri = pString3 + var pString4 *string + if (*source).Model != nil { + pString4 = (*source).Model.ExternalID + } + var pString5 *string + if pString4 != nil { + xstring2 := *pString4 + pString5 = &xstring2 + } + protoArtifact.ExternalId = pString5 + mapStringPProtoValue, err := converter.MapDocArtifactProperties((*source).Model) + if err != nil { + return nil, fmt.Errorf("error setting field Properties: %w", err) + } + protoArtifact.Properties = mapStringPProtoValue + var pMapStringOpenapiMetadataValue *map[string]openapi.MetadataValue + if (*source).Model != nil { + pMapStringOpenapiMetadataValue = (*source).Model.CustomProperties + } + mapStringPProtoValue2, err := converter.MapOpenAPICustomProperties(pMapStringOpenapiMetadataValue) + if err != nil { + return nil, fmt.Errorf("error setting field CustomProperties: %w", err) + } + protoArtifact.CustomProperties = mapStringPProtoValue2 + var pOpenapiArtifactState *openapi.ArtifactState + if (*source).Model != nil { + pOpenapiArtifactState = (*source).Model.State + } + pProtoArtifact_State, err := converter.MapOpenAPIArtifactState(pOpenapiArtifactState) + if err != nil { + return nil, fmt.Errorf("error setting field State: %w", err) + } + protoArtifact.State = pProtoArtifact_State + pProtoArtifact = &protoArtifact + } + return pProtoArtifact, nil +} func (c *OpenAPIToMLMDConverterImpl) ConvertInferenceService(source *converter.OpenAPIModelWrapper[openapi.InferenceService]) (*proto.Context, error) { var pProtoContext *proto.Context if source != nil { diff --git a/internal/converter/mlmd_converter_util_test.go b/internal/converter/mlmd_converter_util_test.go index 9b52bfa1..27ac3d81 100644 --- a/internal/converter/mlmd_converter_util_test.go +++ b/internal/converter/mlmd_converter_util_test.go @@ -323,6 +323,65 @@ func TestMapModelArtifactName(t *testing.T) { assertion.Regexp(".*:v1", *name) } +func TestMapDocArtifactProperties(t *testing.T) { + assertion := setup(t) + + props, err := MapDocArtifactProperties(&openapi.DocArtifact{ + Name: of("v1"), + Description: of("my model art description"), + }) + assertion.Nil(err) + assertion.Equal(1, len(props)) + assertion.Equal("my model art description", props["description"].GetStringValue()) + + props, err = MapModelArtifactProperties(&openapi.ModelArtifact{ + Name: of("v1"), + }) + assertion.Nil(err) + assertion.Equal(0, len(props)) +} + +func TestMapDocArtifactType(t *testing.T) { + assertion := setup(t) + + typeName := MapModelArtifactType(&openapi.ModelArtifact{}) + assertion.NotNil(typeName) + assertion.Equal(constants.ModelArtifactTypeName, *typeName) +} + +func TestMapDocArtifactName(t *testing.T) { + assertion := setup(t) + + name := MapDocArtifactName(&OpenAPIModelWrapper[openapi.DocArtifact]{ + TypeId: 123, + ParentResourceId: of("parent"), + Model: &openapi.DocArtifact{ + Name: of("v1"), + }, + }) + assertion.NotNil(name) + assertion.Equal("parent:v1", *name) + + name = MapDocArtifactName(&OpenAPIModelWrapper[openapi.DocArtifact]{ + TypeId: 123, + ParentResourceId: of("parent"), + Model: &openapi.DocArtifact{ + Name: nil, + }, + }) + assertion.NotNil(name) + assertion.Regexp("parent:.*", *name) + + name = MapDocArtifactName(&OpenAPIModelWrapper[openapi.DocArtifact]{ + TypeId: 123, + Model: &openapi.DocArtifact{ + Name: of("v1"), + }, + }) + assertion.NotNil(name) + assertion.Regexp(".*:v1", *name) +} + func TestMapOpenAPIArtifactState(t *testing.T) { assertion := setup(t) @@ -523,6 +582,12 @@ func TestMapArtifactType(t *testing.T) { assertion.Nil(err) assertion.Equal("model-artifact", artifactType) + artifactType, err = MapArtifactType(&proto.Artifact{ + Type: of(constants.DocArtifactTypeName), + }) + assertion.Nil(err) + assertion.Equal("doc-artifact", artifactType) + artifactType, err = MapArtifactType(&proto.Artifact{ Type: of("Invalid"), }) diff --git a/internal/converter/mlmd_openapi_converter.go b/internal/converter/mlmd_openapi_converter.go index 8bfa3e53..993ba585 100644 --- a/internal/converter/mlmd_openapi_converter.go +++ b/internal/converter/mlmd_openapi_converter.go @@ -35,6 +35,12 @@ type MLMDToOpenAPIConverter interface { // goverter:map Properties ServiceAccountName | MapModelArtifactServiceAccountName ConvertModelArtifact(source *proto.Artifact) (*openapi.ModelArtifact, error) + // goverter:map Name | MapNameFromOwned + // goverter:map . ArtifactType | MapArtifactType + // goverter:map State | MapMLMDArtifactState + // goverter:map Properties Description | MapDescription + ConvertDocArtifact(source *proto.Artifact) (*openapi.DocArtifact, error) + // goverter:map Name | MapNameFromOwned // goverter:map Properties Description | MapDescription ConvertServingEnvironment(source *proto.Context) (*openapi.ServingEnvironment, error) diff --git a/internal/converter/mlmd_openapi_converter_util.go b/internal/converter/mlmd_openapi_converter_util.go index 67f444dc..b6bb863a 100644 --- a/internal/converter/mlmd_openapi_converter_util.go +++ b/internal/converter/mlmd_openapi_converter_util.go @@ -80,15 +80,24 @@ func MapPropertyAuthor(properties map[string]*proto.Value) *string { return MapStringProperty(properties, "author") } -// MODEL ARTIFACT +// ARTIFACT func MapArtifactType(source *proto.Artifact) (string, error) { - if source.Type != nil && *source.Type == constants.ModelArtifactTypeName { + if source.Type == nil { + return "", fmt.Errorf("artifact type is nil") + } + switch *source.Type { + case constants.ModelArtifactTypeName: return "model-artifact", nil + case constants.DocArtifactTypeName: + return "doc-artifact", nil + default: + return "", fmt.Errorf("invalid artifact type found: %v", source.Type) } - return "", fmt.Errorf("invalid artifact type found: %v", source.Type) } +// MODEL ARTIFACT + func MapRegisteredModelState(properties map[string]*proto.Value) *openapi.RegisteredModelState { state, ok := properties["state"] if !ok { diff --git a/internal/converter/openapi_converter.go b/internal/converter/openapi_converter.go index 5d504c6c..eb7486be 100644 --- a/internal/converter/openapi_converter.go +++ b/internal/converter/openapi_converter.go @@ -61,6 +61,12 @@ type OpenAPIConverter interface { // goverter:ignore Id CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties State Author OverrideNotEditableForModelVersion(source OpenapiUpdateWrapper[openapi.ModelVersion]) (openapi.ModelVersion, error) + // Ignore all fields that ARE editable + // goverter:default InitDocArtifactWithUpdate + // goverter:autoMap Existing + // goverter:ignore Id Name ArtifactType CreateTimeSinceEpoch LastUpdateTimeSinceEpoch Description ExternalID CustomProperties Uri State + OverrideNotEditableForDocArtifact(source OpenapiUpdateWrapper[openapi.DocArtifact]) (openapi.DocArtifact, error) + // Ignore all fields that ARE editable // goverter:default InitModelArtifactWithUpdate // goverter:autoMap Existing diff --git a/internal/converter/openapi_converter_test.go b/internal/converter/openapi_converter_test.go index a2f1d431..8b571f41 100644 --- a/internal/converter/openapi_converter_test.go +++ b/internal/converter/openapi_converter_test.go @@ -30,6 +30,9 @@ func newVisitor(t *testing.T, f *ast.File) visitor { "ModelVersion": { obj: openapi.ModelVersion{}, }, + "DocArtifact": { + obj: openapi.DocArtifact{}, + }, "ModelArtifact": { obj: openapi.ModelArtifact{}, }, diff --git a/internal/converter/openapi_converter_util.go b/internal/converter/openapi_converter_util.go index c1bd6c8c..3a492fd7 100644 --- a/internal/converter/openapi_converter_util.go +++ b/internal/converter/openapi_converter_util.go @@ -6,6 +6,7 @@ type OpenAPIModel interface { openapi.RegisteredModel | openapi.ModelVersion | openapi.ModelArtifact | + openapi.DocArtifact | openapi.ServingEnvironment | openapi.InferenceService | openapi.ServeModel @@ -41,6 +42,13 @@ func InitModelVersionWithUpdate(source OpenapiUpdateWrapper[openapi.ModelVersion return openapi.ModelVersion{} } +func InitDocArtifactWithUpdate(source OpenapiUpdateWrapper[openapi.DocArtifact]) openapi.DocArtifact { + if source.Update != nil { + return *source.Update + } + return openapi.DocArtifact{} +} + func InitModelArtifactWithUpdate(source OpenapiUpdateWrapper[openapi.ModelArtifact]) openapi.ModelArtifact { if source.Update != nil { return *source.Update diff --git a/internal/converter/openapi_mlmd_converter.go b/internal/converter/openapi_mlmd_converter.go index 0652d06d..521e2c6c 100644 --- a/internal/converter/openapi_mlmd_converter.go +++ b/internal/converter/openapi_mlmd_converter.go @@ -44,6 +44,14 @@ type OpenAPIToMLMDConverter interface { // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch ConvertModelArtifact(source *OpenAPIModelWrapper[openapi.ModelArtifact]) (*proto.Artifact, error) + // goverter:autoMap Model + // goverter:map . Name | MapDocArtifactName + // goverter:map Model Type | MapDocArtifactType + // goverter:map Model Properties | MapDocArtifactProperties + // goverter:map Model.State State | MapOpenAPIArtifactState + // goverter:ignore state sizeCache unknownFields SystemMetadata CreateTimeSinceEpoch LastUpdateTimeSinceEpoch + ConvertDocArtifact(source *OpenAPIModelWrapper[openapi.DocArtifact]) (*proto.Artifact, error) + // goverter:autoMap Model // goverter:map Model Type | MapServingEnvironmentType // goverter:map Model Properties | MapServingEnvironmentProperties diff --git a/internal/converter/openapi_mlmd_converter_util.go b/internal/converter/openapi_mlmd_converter_util.go index f42ff1d0..de521424 100644 --- a/internal/converter/openapi_mlmd_converter_util.go +++ b/internal/converter/openapi_mlmd_converter_util.go @@ -218,6 +218,41 @@ func MapOpenAPIArtifactState(source *openapi.ArtifactState) (*proto.Artifact_Sta return (*proto.Artifact_State)(&val), nil } +// DOC ARTIFACT + +// get DocArtifact MLMD type name +func MapDocArtifactType(_ *openapi.DocArtifact) *string { + return of(constants.DocArtifactTypeName) +} + +func MapDocArtifactProperties(source *openapi.DocArtifact) (map[string]*proto.Value, error) { + props := make(map[string]*proto.Value) + if source == nil { + return nil, nil + } + if source.Description != nil { + props["description"] = &proto.Value{ + Value: &proto.Value_StringValue{ + StringValue: *source.Description, + }, + } + } + return props, nil +} + +// maps the user-provided name into MLMD one, i.e., prefixing it with either the parent resource id or a generated +// uuid. If not provided, autogenerate the name itself +func MapDocArtifactName(source *OpenAPIModelWrapper[openapi.DocArtifact]) *string { + // openapi.Artifact is defined with optional name, so build arbitrary name for this artifact if missing + var artifactName string + if (*source).Model.Name != nil { + artifactName = *(*source).Model.Name + } else { + artifactName = uuid.New().String() + } + return of(PrefixWhenOwned(source.ParentResourceId, artifactName)) +} + // MODEL ARTIFACT // MapModelArtifactProperties maps ModelArtifact fields to specific MLMD properties diff --git a/internal/mapper/mapper.go b/internal/mapper/mapper.go index 6ac31b5f..271ea743 100644 --- a/internal/mapper/mapper.go +++ b/internal/mapper/mapper.go @@ -27,43 +27,49 @@ func NewMapper(mlmdTypes map[string]int64) *Mapper { // Utilities for OpenAPI --> MLMD mapping, make use of generated Converters func (m *Mapper) MapFromRegisteredModel(registeredModel *openapi.RegisteredModel) (*proto.Context, error) { - ctx, err := m.OpenAPIConverter.ConvertRegisteredModel(&converter.OpenAPIModelWrapper[openapi.RegisteredModel]{ + return m.OpenAPIConverter.ConvertRegisteredModel(&converter.OpenAPIModelWrapper[openapi.RegisteredModel]{ TypeId: m.MLMDTypes[constants.RegisteredModelTypeName], Model: registeredModel, }) - if err != nil { - return nil, err - } - - return ctx, nil } func (m *Mapper) MapFromModelVersion(modelVersion *openapi.ModelVersion, registeredModelId string, registeredModelName *string) (*proto.Context, error) { - ctx, err := m.OpenAPIConverter.ConvertModelVersion(&converter.OpenAPIModelWrapper[openapi.ModelVersion]{ + return m.OpenAPIConverter.ConvertModelVersion(&converter.OpenAPIModelWrapper[openapi.ModelVersion]{ TypeId: m.MLMDTypes[constants.ModelVersionTypeName], Model: modelVersion, ParentResourceId: ®isteredModelId, ModelName: registeredModelName, }) - if err != nil { - return nil, err - } - - return ctx, nil } func (m *Mapper) MapFromModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *string) (*proto.Artifact, error) { - - artifact, err := m.OpenAPIConverter.ConvertModelArtifact(&converter.OpenAPIModelWrapper[openapi.ModelArtifact]{ + return m.OpenAPIConverter.ConvertModelArtifact(&converter.OpenAPIModelWrapper[openapi.ModelArtifact]{ TypeId: m.MLMDTypes[constants.ModelArtifactTypeName], Model: modelArtifact, ParentResourceId: modelVersionId, }) - if err != nil { - return nil, err - } +} - return artifact, nil +func (m *Mapper) MapFromDocArtifact(docArtifact *openapi.DocArtifact, modelVersionId *string) (*proto.Artifact, error) { + return m.OpenAPIConverter.ConvertDocArtifact(&converter.OpenAPIModelWrapper[openapi.DocArtifact]{ + TypeId: m.MLMDTypes[constants.DocArtifactTypeName], + Model: docArtifact, + ParentResourceId: modelVersionId, + }) +} + +func (m *Mapper) MapFromArtifact(artifact *openapi.Artifact, modelVersionId *string) (*proto.Artifact, error) { + if artifact == nil { + return nil, fmt.Errorf("invalid artifact pointer, can't map from nil") + } + if artifact.ModelArtifact != nil { + return m.MapFromModelArtifact(artifact.ModelArtifact, modelVersionId) + } + if artifact.DocArtifact != nil { + return m.MapFromDocArtifact(artifact.DocArtifact, modelVersionId) + } + // TODO: print type on error + return nil, fmt.Errorf("unknown artifact type") } func (m *Mapper) MapFromModelArtifacts(modelArtifacts []openapi.ModelArtifact, modelVersionId *string) ([]*proto.Artifact, error) { @@ -82,41 +88,26 @@ func (m *Mapper) MapFromModelArtifacts(modelArtifacts []openapi.ModelArtifact, m } func (m *Mapper) MapFromServingEnvironment(servingEnvironment *openapi.ServingEnvironment) (*proto.Context, error) { - ctx, err := m.OpenAPIConverter.ConvertServingEnvironment(&converter.OpenAPIModelWrapper[openapi.ServingEnvironment]{ + return m.OpenAPIConverter.ConvertServingEnvironment(&converter.OpenAPIModelWrapper[openapi.ServingEnvironment]{ TypeId: m.MLMDTypes[constants.ServingEnvironmentTypeName], Model: servingEnvironment, }) - if err != nil { - return nil, err - } - - return ctx, nil } func (m *Mapper) MapFromInferenceService(inferenceService *openapi.InferenceService, servingEnvironmentId string) (*proto.Context, error) { - ctx, err := m.OpenAPIConverter.ConvertInferenceService(&converter.OpenAPIModelWrapper[openapi.InferenceService]{ + return m.OpenAPIConverter.ConvertInferenceService(&converter.OpenAPIModelWrapper[openapi.InferenceService]{ TypeId: m.MLMDTypes[constants.InferenceServiceTypeName], Model: inferenceService, ParentResourceId: &servingEnvironmentId, }) - if err != nil { - return nil, err - } - - return ctx, nil } func (m *Mapper) MapFromServeModel(serveModel *openapi.ServeModel, inferenceServiceId string) (*proto.Execution, error) { - ctx, err := m.OpenAPIConverter.ConvertServeModel(&converter.OpenAPIModelWrapper[openapi.ServeModel]{ + return m.OpenAPIConverter.ConvertServeModel(&converter.OpenAPIModelWrapper[openapi.ServeModel]{ TypeId: m.MLMDTypes[constants.ServeModelTypeName], Model: serveModel, ParentResourceId: &inferenceServiceId, }) - if err != nil { - return nil, err - } - - return ctx, nil } // Utilities for MLMD --> OpenAPI mapping, make use of generated Converters @@ -133,6 +124,33 @@ func (m *Mapper) MapToModelArtifact(art *proto.Artifact) (*openapi.ModelArtifact return mapTo(art, m.MLMDTypes, constants.ModelArtifactTypeName, m.MLMDConverter.ConvertModelArtifact) } +func (m *Mapper) MapToDocArtifact(art *proto.Artifact) (*openapi.DocArtifact, error) { + return mapTo(art, m.MLMDTypes, constants.DocArtifactTypeName, m.MLMDConverter.ConvertDocArtifact) +} + +func (m *Mapper) MapToArtifact(art *proto.Artifact) (*openapi.Artifact, error) { + if art == nil { + return nil, fmt.Errorf("invalid artifact pointer, can't map from nil") + } + if art.GetType() == "" { + return nil, fmt.Errorf("invalid artifact type, can't map from nil") + } + switch art.GetType() { + case constants.ModelArtifactTypeName: + ma, err := m.MapToModelArtifact(art) + return &openapi.Artifact{ + ModelArtifact: ma, + }, err + case constants.DocArtifactTypeName: + da, err := m.MapToDocArtifact(art) + return &openapi.Artifact{ + DocArtifact: da, + }, err + default: + return nil, fmt.Errorf("unknown artifact type: %s", art.GetType()) + } +} + func (m *Mapper) MapToServingEnvironment(ctx *proto.Context) (*openapi.ServingEnvironment, error) { return mapTo(ctx, m.MLMDTypes, constants.ServingEnvironmentTypeName, m.MLMDConverter.ConvertServingEnvironment) } diff --git a/internal/mapper/mapper_test.go b/internal/mapper/mapper_test.go index 4996e14c..7ad7b98a 100644 --- a/internal/mapper/mapper_test.go +++ b/internal/mapper/mapper_test.go @@ -14,15 +14,17 @@ const ( invalidTypeId = int64(9999) registeredModelTypeId = int64(1) modelVersionTypeId = int64(2) - modelArtifactTypeId = int64(3) - servingEnvironmentTypeId = int64(4) - inferenceServiceTypeId = int64(5) - serveModelTypeId = int64(6) + docArtifactTypeId = int64(3) + modelArtifactTypeId = int64(4) + servingEnvironmentTypeId = int64(5) + inferenceServiceTypeId = int64(6) + serveModelTypeId = int64(7) ) var typesMap = map[string]int64{ constants.RegisteredModelTypeName: registeredModelTypeId, constants.ModelVersionTypeName: modelVersionTypeId, + constants.DocArtifactTypeName: docArtifactTypeId, constants.ModelArtifactTypeName: modelArtifactTypeId, constants.ServingEnvironmentTypeName: servingEnvironmentTypeId, constants.InferenceServiceTypeName: inferenceServiceTypeId, @@ -53,10 +55,23 @@ func TestMapFromModelVersion(t *testing.T) { assertion.Equal(modelVersionTypeId, ctx.GetTypeId()) } +func TestMapFromDocArtifact(t *testing.T) { + assertion, m := setup(t) + + ctx, err := m.MapFromArtifact(&openapi.Artifact{ + DocArtifact: &openapi.DocArtifact{Name: of("DocArtifact")}, + }, of("2")) + assertion.Nil(err) + assertion.Equal("2:DocArtifact", ctx.GetName()) + assertion.Equal(docArtifactTypeId, ctx.GetTypeId()) +} + func TestMapFromModelArtifact(t *testing.T) { assertion, m := setup(t) - ctx, err := m.MapFromModelArtifact(&openapi.ModelArtifact{Name: of("ModelArtifact")}, of("2")) + ctx, err := m.MapFromArtifact(&openapi.Artifact{ + ModelArtifact: &openapi.ModelArtifact{Name: of("ModelArtifact")}, + }, of("2")) assertion.Nil(err) assertion.Equal("2:ModelArtifact", ctx.GetName()) assertion.Equal(modelArtifactTypeId, ctx.GetTypeId()) @@ -167,9 +182,18 @@ func TestMapToModelVersionInvalid(t *testing.T) { assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.ModelVersionTypeName), err.Error()) } +func TestMapToDocArtifact(t *testing.T) { + assertion, m := setup(t) + _, err := m.MapToArtifact(&proto.Artifact{ + TypeId: of(docArtifactTypeId), + Type: of(constants.DocArtifactTypeName), + }) + assertion.Nil(err) +} + func TestMapToModelArtifact(t *testing.T) { assertion, m := setup(t) - _, err := m.MapToModelArtifact(&proto.Artifact{ + _, err := m.MapToArtifact(&proto.Artifact{ TypeId: of(modelArtifactTypeId), Type: of(constants.ModelArtifactTypeName), }) @@ -178,21 +202,21 @@ func TestMapToModelArtifact(t *testing.T) { func TestMapToModelArtifactMissingType(t *testing.T) { assertion, m := setup(t) - _, err := m.MapToModelArtifact(&proto.Artifact{ + _, err := m.MapToArtifact(&proto.Artifact{ TypeId: of(modelArtifactTypeId), }) assertion.NotNil(err) - assertion.Equal("error setting field ArtifactType: invalid artifact type found: ", err.Error()) + assertion.Equal("invalid artifact type, can't map from nil", err.Error()) } -func TestMapToModelArtifactInvalid(t *testing.T) { +func TestMapToArtifactInvalid(t *testing.T) { assertion, m := setup(t) - _, err := m.MapToModelArtifact(&proto.Artifact{ + _, err := m.MapToArtifact(&proto.Artifact{ TypeId: of(invalidTypeId), Type: of("odh.OtherEntity"), }) assertion.NotNil(err) - assertion.Equal(fmt.Sprintf("invalid entity: expected %s but received odh.OtherEntity, please check the provided id", constants.ModelArtifactTypeName), err.Error()) + assertion.Equal("unknown artifact type: odh.OtherEntity", err.Error()) } func TestMapToServingEnvironment(t *testing.T) { diff --git a/internal/mlmdtypes/mlmdtypes.go b/internal/mlmdtypes/mlmdtypes.go index f8ab687d..7d6b4220 100644 --- a/internal/mlmdtypes/mlmdtypes.go +++ b/internal/mlmdtypes/mlmdtypes.go @@ -14,6 +14,7 @@ var ( registeredModelTypeName = apiutils.Of(constants.RegisteredModelTypeName) modelVersionTypeName = apiutils.Of(constants.ModelVersionTypeName) modelArtifactTypeName = apiutils.Of(constants.ModelArtifactTypeName) + docArtifactTypeName = apiutils.Of(constants.DocArtifactTypeName) servingEnvironmentTypeName = apiutils.Of(constants.ServingEnvironmentTypeName) inferenceServiceTypeName = apiutils.Of(constants.InferenceServiceTypeName) serveModelTypeName = apiutils.Of(constants.ServeModelTypeName) @@ -50,6 +51,16 @@ func CreateMLMDTypes(cc grpc.ClientConnInterface) (map[string]int64, error) { }, } + docArtifactReq := proto.PutArtifactTypeRequest{ + CanAddFields: canAddFields, + ArtifactType: &proto.ArtifactType{ + Name: docArtifactTypeName, + Properties: map[string]proto.PropertyType{ + "description": proto.PropertyType_STRING, + }, + }, + } + modelArtifactReq := proto.PutArtifactTypeRequest{ CanAddFields: canAddFields, ArtifactType: &proto.ArtifactType{ @@ -112,6 +123,11 @@ func CreateMLMDTypes(cc grpc.ClientConnInterface) (map[string]int64, error) { return nil, fmt.Errorf("error setting up context type %s: %v", *modelVersionTypeName, err) } + docArtifactResp, err := client.PutArtifactType(context.Background(), &docArtifactReq) + if err != nil { + return nil, fmt.Errorf("error setting up artifact type %s: %v", *docArtifactTypeName, err) + } + modelArtifactResp, err := client.PutArtifactType(context.Background(), &modelArtifactReq) if err != nil { return nil, fmt.Errorf("error setting up artifact type %s: %v", *modelArtifactTypeName, err) @@ -135,6 +151,7 @@ func CreateMLMDTypes(cc grpc.ClientConnInterface) (map[string]int64, error) { typesMap := map[string]int64{ constants.RegisteredModelTypeName: registeredModelResp.GetTypeId(), constants.ModelVersionTypeName: modelVersionResp.GetTypeId(), + constants.DocArtifactTypeName: docArtifactResp.GetTypeId(), constants.ModelArtifactTypeName: modelArtifactResp.GetTypeId(), constants.ServingEnvironmentTypeName: servingEnvironmentResp.GetTypeId(), constants.InferenceServiceTypeName: inferenceServiceResp.GetTypeId(), diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index 4d617174..e1134a4c 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -11,8 +11,6 @@ package openapi import ( "context" - "errors" - "net/http" "github.com/opendatahub-io/model-registry/internal/apiutils" "github.com/opendatahub-io/model-registry/internal/converter" @@ -111,17 +109,12 @@ func (s *ModelRegistryServiceAPIService) CreateModelVersion(ctx context.Context, // CreateModelVersionArtifact - Create an Artifact in a ModelVersion func (s *ModelRegistryServiceAPIService) CreateModelVersionArtifact(ctx context.Context, modelversionId string, artifact model.Artifact) (ImplResponse, error) { - if artifact.ModelArtifact == nil { - return Response(http.StatusNotImplemented, nil), errors.New("unsupported artifactType") - } - result, err := s.coreApi.UpsertModelArtifact(artifact.ModelArtifact, &modelversionId) + result, err := s.coreApi.UpsertArtifact(&artifact, &modelversionId) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - artifactResult := model.Artifact{ - ModelArtifact: result, - } - return Response(201, artifactResult), nil + return Response(201, result), nil + // return Response(http.StatusNotImplemented, nil), errors.New("unsupported artifactType") // TODO return Response(200, Artifact{}), nil // TODO return Response(401, Error{}), nil // TODO return Response(404, Error{}), nil @@ -354,7 +347,7 @@ func (s *ModelRegistryServiceAPIService) GetModelVersionArtifacts(ctx context.Co if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } - result, err := s.coreApi.GetModelArtifacts(listOpts, &modelversionId) + result, err := s.coreApi.GetArtifacts(listOpts, &modelversionId) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } diff --git a/pkg/api/api.go b/pkg/api/api.go index dd2dd4bc..33f16540 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -50,6 +50,14 @@ type ModelRegistryApi interface { // if registeredModelId is provided, return all ModelVersion instances belonging to a specific RegisteredModel GetModelVersions(listOptions ListOptions, registeredModelId *string) (*openapi.ModelVersionList, error) + // ARTIFACT + + UpsertArtifact(artifact *openapi.Artifact, modelVersionId *string) (*openapi.Artifact, error) + + GetArtifactById(id string) (*openapi.Artifact, error) + + GetArtifacts(listOptions ListOptions, modelVersionId *string) (*openapi.ArtifactList, error) + // MODEL ARTIFACT // UpsertModelArtifact create a new Artifact or update an Artifact associated to a specific diff --git a/pkg/core/core.go b/pkg/core/core.go index e04a5dd5..d812130e 100644 --- a/pkg/core/core.go +++ b/pkg/core/core.go @@ -21,6 +21,7 @@ var ( registeredModelTypeName = apiutils.Of(constants.RegisteredModelTypeName) modelVersionTypeName = apiutils.Of(constants.ModelVersionTypeName) modelArtifactTypeName = apiutils.Of(constants.ModelArtifactTypeName) + docArtifactTypeName = apiutils.Of(constants.DocArtifactTypeName) servingEnvironmentTypeName = apiutils.Of(constants.ServingEnvironmentTypeName) inferenceServiceTypeName = apiutils.Of(constants.InferenceServiceTypeName) serveModelTypeName = apiutils.Of(constants.ServeModelTypeName) @@ -72,6 +73,12 @@ func BuildTypesMap(cc grpc.ClientConnInterface) (map[string]int64, error) { if err != nil { return nil, fmt.Errorf("error getting context type %s: %v", *modelVersionTypeName, err) } + docArtifactResp, err := client.GetArtifactType(context.Background(), &proto.GetArtifactTypeRequest{ + TypeName: docArtifactTypeName, + }) + if err != nil { + return nil, fmt.Errorf("error getting artifact type %s: %v", *docArtifactTypeName, err) + } modelArtifactArtifactTypeReq := proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, } @@ -104,6 +111,7 @@ func BuildTypesMap(cc grpc.ClientConnInterface) (map[string]int64, error) { typesMap := map[string]int64{ constants.RegisteredModelTypeName: registeredModelResp.ContextType.GetId(), constants.ModelVersionTypeName: modelVersionResp.ContextType.GetId(), + constants.DocArtifactTypeName: docArtifactResp.ArtifactType.GetId(), constants.ModelArtifactTypeName: modelArtifactResp.ArtifactType.GetId(), constants.ServingEnvironmentTypeName: servingEnvironmentResp.ContextType.GetId(), constants.InferenceServiceTypeName: inferenceServiceResp.ContextType.GetId(), @@ -366,7 +374,8 @@ func (serv *ModelRegistryService) UpsertModelVersion(modelVersion *openapi.Model _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ ParentContexts: []*proto.ParentContext{{ ChildId: modelId, - ParentId: registeredModelId}}, + ParentId: registeredModelId, + }}, TransactionOptions: &proto.TransactionOptions{}, }) if err != nil { @@ -452,11 +461,11 @@ func (serv *ModelRegistryService) getModelVersionByArtifactId(id string) (*opena } if len(getParentResp.Contexts) > 1 { - return nil, fmt.Errorf("multiple model versions found for model artifact %s", id) + return nil, fmt.Errorf("multiple model versions found for artifact %s", id) } if len(getParentResp.Contexts) == 0 { - return nil, fmt.Errorf("no model version found for model artifact %s", id) + return nil, fmt.Errorf("no model version found for artifact %s", id) } modelVersion, err := serv.mapper.MapToModelVersion(getParentResp.Contexts[0]) @@ -542,60 +551,94 @@ func (serv *ModelRegistryService) GetModelVersions(listOptions api.ListOptions, return &toReturn, nil } -// MODEL ARTIFACTS - -// UpsertModelArtifact creates a new model artifact if the provided model artifact's ID is nil, -// or updates an existing model artifact if the ID is provided. -// If a model version ID is provided and the model artifact is newly created, establishes an -// explicit attribution between the model version and the created model artifact. -func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *string) (*openapi.ModelArtifact, error) { - var err error - var existing *openapi.ModelArtifact - - if modelArtifact.Id == nil { - // create - glog.Info("Creating new model artifact") - if modelVersionId == nil { - return nil, fmt.Errorf("missing model version id, cannot create model artifact without model version") +// ARTIFACTS + +// UpsertArtifact creates a new artifact if the provided artifact's ID is nil, or updates an existing artifact if the +// ID is provided. +// A model version ID must be provided to disambiguate between artifacts. +// Upon creation, new artifacts will be associated with their corresponding model version. +func (serv *ModelRegistryService) UpsertArtifact(artifact *openapi.Artifact, modelVersionId *string) (*openapi.Artifact, error) { + if artifact == nil { + return nil, fmt.Errorf("invalid artifact pointer, can't upsert nil") + } + creating := false + if ma := artifact.ModelArtifact; ma != nil { + if ma.Id == nil { + creating = true + glog.Info("Creating model artifact") + if modelVersionId == nil { + return nil, fmt.Errorf("missing model version id, cannot create artifact without model version") + } + _, err := serv.GetModelVersionById(*modelVersionId) + if err != nil { + return nil, fmt.Errorf("no model version found for id %s", *modelVersionId) + } + } else { + glog.Info("Updating model artifact") + existing, err := serv.GetModelArtifactById(*ma.Id) + if err != nil { + return nil, err + } + + withNotEditable, err := serv.openapiConv.OverrideNotEditableForModelArtifact(converter.NewOpenapiUpdateWrapper(existing, ma)) + if err != nil { + return nil, err + } + ma = &withNotEditable + + _, err = serv.getModelVersionByArtifactId(*ma.Id) + if err != nil { + return nil, err + } } - _, err = serv.GetModelVersionById(*modelVersionId) - if err != nil { - return nil, err + } else if da := artifact.DocArtifact; da != nil { + if da.Id == nil { + creating = true + glog.Info("Creating doc artifact") + if modelVersionId == nil { + return nil, fmt.Errorf("missing model version id, cannot create artifact without model version") + } + _, err := serv.GetModelVersionById(*modelVersionId) + if err != nil { + return nil, fmt.Errorf("no model version found for id %s", *modelVersionId) + } + } else { + glog.Info("Updating doc artifact") + existing, err := serv.GetArtifactById(*da.Id) + if err != nil { + return nil, err + } + if existing.DocArtifact == nil { + return nil, fmt.Errorf("mismatched types, artifact with id %s is not a doc artifact", *da.Id) + } + + withNotEditable, err := serv.openapiConv.OverrideNotEditableForDocArtifact(converter.NewOpenapiUpdateWrapper(existing.DocArtifact, da)) + if err != nil { + return nil, err + } + da = &withNotEditable + + _, err = serv.getModelVersionByArtifactId(*da.Id) + if err != nil { + return nil, err + } } } else { - // update - glog.Infof("Updating model artifact %s", *modelArtifact.Id) - existing, err = serv.GetModelArtifactById(*modelArtifact.Id) - if err != nil { - return nil, err - } - - withNotEditable, err := serv.openapiConv.OverrideNotEditableForModelArtifact(converter.NewOpenapiUpdateWrapper(existing, modelArtifact)) - if err != nil { - return nil, err - } - modelArtifact = &withNotEditable - - _, err = serv.getModelVersionByArtifactId(*modelArtifact.Id) - if err != nil { - return nil, err - } + return nil, fmt.Errorf("invalid artifact type, must be either ModelArtifact or DocArtifact") } - - artifact, err := serv.mapper.MapFromModelArtifact(modelArtifact, modelVersionId) + pa, err := serv.mapper.MapFromArtifact(artifact, modelVersionId) if err != nil { return nil, err } - artifactsResp, err := serv.mlmdClient.PutArtifacts(context.Background(), &proto.PutArtifactsRequest{ - Artifacts: []*proto.Artifact{artifact}, + Artifacts: []*proto.Artifact{pa}, }) if err != nil { return nil, err } - // add explicit Attribution between Artifact and ModelVersion - if modelVersionId != nil && modelArtifact.Id == nil { + if creating { + // add explicit Attribution between Artifact and ModelVersion modelVersionId, err := converter.StringToInt64(modelVersionId) if err != nil { return nil, err @@ -617,15 +660,10 @@ func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.Mod } idAsString := converter.Int64ToString(&artifactsResp.ArtifactIds[0]) - mapped, err := serv.GetModelArtifactById(*idAsString) - if err != nil { - return nil, err - } - return mapped, nil + return serv.GetArtifactById(*idAsString) } -// GetModelArtifactById retrieves a model artifact by its unique identifier (ID). -func (serv *ModelRegistryService) GetModelArtifactById(id string) (*openapi.ModelArtifact, error) { +func (serv *ModelRegistryService) GetArtifactById(id string) (*openapi.Artifact, error) { idAsInt, err := converter.StringToInt64(&id) if err != nil { return nil, err @@ -637,26 +675,88 @@ func (serv *ModelRegistryService) GetModelArtifactById(id string) (*openapi.Mode if err != nil { return nil, err } - if len(artifactsResp.Artifacts) > 1 { - return nil, fmt.Errorf("multiple model artifacts found for id %s", id) + return nil, fmt.Errorf("multiple artifacts found for id %s", id) } - if len(artifactsResp.Artifacts) == 0 { - return nil, fmt.Errorf("no model artifact found for id %s", id) + return nil, fmt.Errorf("no artifact found for id %s", id) + } + return serv.mapper.MapToArtifact(artifactsResp.Artifacts[0]) +} + +func (serv *ModelRegistryService) GetArtifacts(listOptions api.ListOptions, modelVersionId *string) (*openapi.ArtifactList, error) { + listOperationOptions, err := apiutils.BuildListOperationOptions(listOptions) + if err != nil { + return nil, err + } + var artifacts []*proto.Artifact + var nextPageToken *string + if modelVersionId == nil { + return nil, fmt.Errorf("missing model version id, cannot get artifacts without model version") + } + ctxId, err := converter.StringToInt64(modelVersionId) + if err != nil { + return nil, err + } + artifactsResp, err := serv.mlmdClient.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ + ContextId: ctxId, + Options: listOperationOptions, + }) + if err != nil { + return nil, err + } + artifacts = artifactsResp.Artifacts + nextPageToken = artifactsResp.NextPageToken + + results := []openapi.Artifact{} + for _, a := range artifacts { + mapped, err := serv.mapper.MapToArtifact(a) + if err != nil { + return nil, err + } + results = append(results, *mapped) + } + + toReturn := openapi.ArtifactList{ + NextPageToken: apiutils.ZeroIfNil(nextPageToken), + PageSize: apiutils.ZeroIfNil(listOptions.PageSize), + Size: int32(len(results)), + Items: results, } + return &toReturn, nil +} - result, err := serv.mapper.MapToModelArtifact(artifactsResp.Artifacts[0]) +// MODEL ARTIFACTS + +// UpsertModelArtifact creates a new model artifact if the provided model artifact's ID is nil, +// or updates an existing model artifact if the ID is provided. +// If a model version ID is provided and the model artifact is newly created, establishes an +// explicit attribution between the model version and the created model artifact. +func (serv *ModelRegistryService) UpsertModelArtifact(modelArtifact *openapi.ModelArtifact, modelVersionId *string) (*openapi.ModelArtifact, error) { + art, err := serv.UpsertArtifact(&openapi.Artifact{ + ModelArtifact: modelArtifact, + }, modelVersionId) if err != nil { return nil, err } + return art.ModelArtifact, err +} - return result, nil +// GetModelArtifactById retrieves a model artifact by its unique identifier (ID). +func (serv *ModelRegistryService) GetModelArtifactById(id string) (*openapi.ModelArtifact, error) { + art, err := serv.GetArtifactById(id) + if err != nil { + return nil, err + } + ma := art.ModelArtifact + if ma == nil { + return nil, fmt.Errorf("artifact with id %s is not a model artifact", id) + } + return ma, err } // GetModelArtifactByInferenceService retrieves the model artifact associated with the specified inference service ID. func (serv *ModelRegistryService) GetModelArtifactByInferenceService(inferenceServiceId string) (*openapi.ModelArtifact, error) { - mv, err := serv.GetModelVersionByInferenceService(inferenceServiceId) if err != nil { return nil, err @@ -992,7 +1092,8 @@ func (serv *ModelRegistryService) UpsertInferenceService(inferenceService *opena _, err = serv.mlmdClient.PutParentContexts(context.Background(), &proto.PutParentContextsRequest{ ParentContexts: []*proto.ParentContext{{ ChildId: inferenceServiceId, - ParentId: servingEnvironmentId}}, + ParentId: servingEnvironmentId, + }}, TransactionOptions: &proto.TransactionOptions{}, }) if err != nil { diff --git a/pkg/core/core_test.go b/pkg/core/core_test.go index e4473253..a031c541 100644 --- a/pkg/core/core_test.go +++ b/pkg/core/core_test.go @@ -53,9 +53,7 @@ type CoreTestSuite struct { mlmdClient proto.MetadataStoreServiceClient } -var ( - canAddFields = apiutils.Of(true) -) +var canAddFields = apiutils.Of(true) func TestRunCoreTestSuite(t *testing.T) { // before all @@ -257,6 +255,12 @@ func (suite *CoreTestSuite) TestModelRegistryStartupWithExistingEmptyTypes() { Name: modelVersionTypeName, }, } + docArtifactReq := proto.PutArtifactTypeRequest{ + CanAddFields: canAddFields, + ArtifactType: &proto.ArtifactType{ + Name: docArtifactTypeName, + }, + } modelArtifactReq := proto.PutArtifactTypeRequest{ CanAddFields: canAddFields, ArtifactType: &proto.ArtifactType{ @@ -286,6 +290,8 @@ func (suite *CoreTestSuite) TestModelRegistryStartupWithExistingEmptyTypes() { suite.Nil(err) _, err = suite.mlmdClient.PutContextType(context.Background(), &modelVersionReq) suite.Nil(err) + _, err = suite.mlmdClient.PutArtifactType(context.Background(), &docArtifactReq) + suite.Nil(err) _, err = suite.mlmdClient.PutArtifactType(context.Background(), &modelArtifactReq) suite.Nil(err) _, err = suite.mlmdClient.PutContextType(context.Background(), &servingEnvironmentReq) @@ -302,6 +308,9 @@ func (suite *CoreTestSuite) TestModelRegistryStartupWithExistingEmptyTypes() { modelVersionResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ TypeName: modelVersionTypeName, }) + docArtifactResp, _ := suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + TypeName: docArtifactTypeName, + }) modelArtifactResp, _ := suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, }) @@ -317,6 +326,7 @@ func (suite *CoreTestSuite) TestModelRegistryStartupWithExistingEmptyTypes() { suite.Equal(0, len(regModelResp.ContextType.Properties)) suite.Equal(0, len(modelVersionResp.ContextType.Properties)) + suite.Equal(0, len(docArtifactResp.ArtifactType.Properties)) suite.Equal(0, len(modelArtifactResp.ArtifactType.Properties)) suite.Equal(0, len(servingEnvResp.ContextType.Properties)) suite.Equal(0, len(inferenceServiceResp.ContextType.Properties)) @@ -341,6 +351,13 @@ func (suite *CoreTestSuite) TestModelRegistryStartupWithExistingEmptyTypes() { suite.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) suite.Equal(5, len(modelVersionResp.ContextType.Properties)) + docArtifactResp, _ = suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + TypeName: docArtifactTypeName, + }) + suite.NotNilf(docArtifactResp.ArtifactType, "doc artifact type %s should exists", *docArtifactTypeName) + suite.Equal(*docArtifactTypeName, *docArtifactResp.ArtifactType.Name) + suite.Equal(1, len(docArtifactResp.ArtifactType.Properties)) + modelArtifactResp, _ = suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, }) @@ -388,10 +405,16 @@ func (suite *CoreTestSuite) TestModelRegistryTypes() { suite.NotNilf(modelVersionResp.ContextType, "model version type %s should exists", *modelVersionTypeName) suite.Equal(*modelVersionTypeName, *modelVersionResp.ContextType.Name) + docArtifactResp, _ := suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ + TypeName: docArtifactTypeName, + }) + suite.NotNilf(docArtifactResp.ArtifactType, "doc artifact type %s should exists", *docArtifactTypeName) + suite.Equal(*docArtifactTypeName, *docArtifactResp.ArtifactType.Name) + modelArtifactResp, _ := suite.mlmdClient.GetArtifactType(ctx, &proto.GetArtifactTypeRequest{ TypeName: modelArtifactTypeName, }) - suite.NotNilf(modelArtifactResp.ArtifactType, "model version type %s should exists", *modelArtifactTypeName) + suite.NotNilf(modelArtifactResp.ArtifactType, "model artifact type %s should exists", *modelArtifactTypeName) suite.Equal(*modelArtifactTypeName, *modelArtifactResp.ArtifactType.Name) servingEnvResp, _ := suite.mlmdClient.GetContextType(ctx, &proto.GetContextTypeRequest{ @@ -1345,6 +1368,251 @@ func (suite *CoreTestSuite) TestGetModelVersions() { suite.Equal(*converter.Int64ToString(createdVersionId3), *getAllByRegModel.Items[1].Id) } +// ARTIFACTS + +func (suite *CoreTestSuite) TestCreateArtifact() { + // create mode registry service + service := suite.setupModelRegistryService() + + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) + + createdArt, err := service.UpsertArtifact(&openapi.Artifact{ + DocArtifact: &openapi.DocArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + Description: &artifactDescription, + CustomProperties: &map[string]openapi.MetadataValue{ + "custom_string_prop": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &customString, + }, + }, + }, + }, + }, &modelVersionId) + suite.Nilf(err, "error creating new artifact for %d: %v", modelVersionId, err) + + docArtifact := createdArt.DocArtifact + suite.NotNilf(docArtifact, "error creating new artifact for %d", modelVersionId) + state, _ := openapi.NewArtifactStateFromValue(artifactState) + suite.NotNil(docArtifact.Id, "created artifact id should not be nil") + suite.Equal(artifactName, *docArtifact.Name) + suite.Equal(*state, *docArtifact.State) + suite.Equal(artifactUri, *docArtifact.Uri) + suite.Equal(artifactDescription, *docArtifact.Description) + suite.Equal(customString, *(*docArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) +} + +func (suite *CoreTestSuite) TestCreateArtifactFailure() { + // create mode registry service + service := suite.setupModelRegistryService() + + modelVersionId := "9998" + + var artifact openapi.Artifact + artifact.DocArtifact = &openapi.DocArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "custom_string_prop": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &customString, + }, + }, + }, + } + + _, err := service.UpsertArtifact(&artifact, nil) + suite.NotNil(err) + suite.Equal("missing model version id, cannot create artifact without model version", err.Error()) + + _, err = service.UpsertArtifact(&artifact, &modelVersionId) + suite.NotNil(err) + suite.Equal("no model version found for id 9998", err.Error()) +} + +func (suite *CoreTestSuite) TestUpdateArtifact() { + // create mode registry service + service := suite.setupModelRegistryService() + + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) + + createdArtifact, err := service.UpsertArtifact(&openapi.Artifact{ + DocArtifact: &openapi.DocArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "custom_string_prop": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &customString, + }, + }, + }, + }, + }, &modelVersionId) + suite.Nilf(err, "error creating new artifact for %d", modelVersionId) + + newState := "MARKED_FOR_DELETION" + createdArtifact.DocArtifact.State = (*openapi.ArtifactState)(&newState) + updatedArtifact, err := service.UpsertArtifact(createdArtifact, &modelVersionId) + suite.Nilf(err, "error updating artifact for %d: %v", modelVersionId, err) + + createdArtifactId, _ := converter.StringToInt64(createdArtifact.DocArtifact.Id) + updatedArtifactId, _ := converter.StringToInt64(updatedArtifact.DocArtifact.Id) + suite.Equal(createdArtifactId, updatedArtifactId) + + getById, err := suite.mlmdClient.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ + ArtifactIds: []int64{*createdArtifactId}, + }) + suite.Nilf(err, "error getting artifact by id %d", createdArtifactId) + + suite.Equal(*createdArtifactId, *getById.Artifacts[0].Id) + suite.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.DocArtifact.Name), *getById.Artifacts[0].Name) + suite.Equal(string(newState), getById.Artifacts[0].State.String()) + suite.Equal(*createdArtifact.DocArtifact.Uri, *getById.Artifacts[0].Uri) + suite.Equal(*(*createdArtifact.DocArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) +} + +func (suite *CoreTestSuite) TestUpdateArtifactFailure() { + // create mode registry service + service := suite.setupModelRegistryService() + + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) + + createdArtifact, err := service.UpsertArtifact(&openapi.Artifact{ + DocArtifact: &openapi.DocArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "custom_string_prop": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &customString, + }, + }, + }, + }, + }, &modelVersionId) + suite.Nilf(err, "error creating new artifact for model version %s", modelVersionId) + suite.NotNilf(createdArtifact.DocArtifact.Id, "created model artifact should not have nil Id") + + newState := "MARKED_FOR_DELETION" + createdArtifact.DocArtifact.State = (*openapi.ArtifactState)(&newState) + updatedArtifact, err := service.UpsertArtifact(createdArtifact, &modelVersionId) + suite.Nilf(err, "error updating artifact for %d: %v", modelVersionId, err) + + wrongId := "5555" + updatedArtifact.DocArtifact.Id = &wrongId + _, err = service.UpsertArtifact(updatedArtifact, &modelVersionId) + suite.NotNil(err) + suite.Equal(fmt.Sprintf("no artifact found for id %s", wrongId), err.Error()) +} + +func (suite *CoreTestSuite) TestGetArtifactById() { + // create mode registry service + service := suite.setupModelRegistryService() + + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) + + createdArtifact, err := service.UpsertArtifact(&openapi.Artifact{ + DocArtifact: &openapi.DocArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + CustomProperties: &map[string]openapi.MetadataValue{ + "custom_string_prop": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &customString, + }, + }, + }, + }, + }, &modelVersionId) + suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) + + createdArtifactId, _ := converter.StringToInt64(createdArtifact.DocArtifact.Id) + + getById, err := service.GetArtifactById(*createdArtifact.DocArtifact.Id) + suite.Nilf(err, "error getting artifact by id %d", createdArtifactId) + + state, _ := openapi.NewArtifactStateFromValue(artifactState) + suite.NotNil(createdArtifact.DocArtifact.Id, "created artifact id should not be nil") + suite.Equal(artifactName, *getById.DocArtifact.Name) + suite.Equal(*state, *getById.DocArtifact.State) + suite.Equal(artifactUri, *getById.DocArtifact.Uri) + suite.Equal(customString, *(*getById.DocArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) + + suite.Equal(*createdArtifact, *getById, "artifacts returned during creation and on get by id should be equal") +} + +func (suite *CoreTestSuite) TestGetArtifacts() { + // create mode registry service + service := suite.setupModelRegistryService() + + modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) + + secondArtifactName := "second-name" + secondArtifactExtId := "second-ext-id" + secondArtifactUri := "second-uri" + + createdArtifact1, err := service.UpsertArtifact(&openapi.Artifact{ + ModelArtifact: &openapi.ModelArtifact{ + Name: &artifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &artifactUri, + ExternalID: &artifactExtId, + CustomProperties: &map[string]openapi.MetadataValue{ + "custom_string_prop": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &customString, + }, + }, + }, + }, + }, &modelVersionId) + suite.Nilf(err, "error creating new artifact for %d", modelVersionId) + createdArtifact2, err := service.UpsertArtifact(&openapi.Artifact{ + DocArtifact: &openapi.DocArtifact{ + Name: &secondArtifactName, + State: (*openapi.ArtifactState)(&artifactState), + Uri: &secondArtifactUri, + ExternalID: &secondArtifactExtId, + CustomProperties: &map[string]openapi.MetadataValue{ + "custom_string_prop": { + MetadataStringValue: &openapi.MetadataStringValue{ + StringValue: &customString, + }, + }, + }, + }, + }, &modelVersionId) + suite.Nilf(err, "error creating new artifact for %d", modelVersionId) + + createdArtifactId1, _ := converter.StringToInt64(createdArtifact1.ModelArtifact.Id) + createdArtifactId2, _ := converter.StringToInt64(createdArtifact2.DocArtifact.Id) + + getAll, err := service.GetArtifacts(api.ListOptions{}, &modelVersionId) + suite.Nilf(err, "error getting all model artifacts") + suite.Equalf(int32(2), getAll.Size, "expected two artifacts") + + suite.Equal(*converter.Int64ToString(createdArtifactId1), *getAll.Items[0].ModelArtifact.Id) + suite.Equal(*converter.Int64ToString(createdArtifactId2), *getAll.Items[1].DocArtifact.Id) + + orderByLastUpdate := "LAST_UPDATE_TIME" + getAllByModelVersion, err := service.GetArtifacts(api.ListOptions{ + OrderBy: &orderByLastUpdate, + SortOrder: &descOrderDirection, + }, &modelVersionId) + suite.Nilf(err, "error getting all model artifacts for %d", modelVersionId) + suite.Equalf(int32(2), getAllByModelVersion.Size, "expected 2 artifacts for model version %d", modelVersionId) + + suite.Equal(*converter.Int64ToString(createdArtifactId1), *getAllByModelVersion.Items[1].ModelArtifact.Id) + suite.Equal(*converter.Int64ToString(createdArtifactId2), *getAllByModelVersion.Items[0].DocArtifact.Id) +} + // MODEL ARTIFACTS func (suite *CoreTestSuite) TestCreateModelArtifact() { @@ -1353,7 +1621,7 @@ func (suite *CoreTestSuite) TestCreateModelArtifact() { modelVersionId := suite.registerModelVersion(service, nil, nil, nil, nil) - modelArtifact := &openapi.ModelArtifact{ + modelArtifact, err := service.UpsertModelArtifact(&openapi.ModelArtifact{ Name: &artifactName, State: (*openapi.ArtifactState)(&artifactState), Uri: &artifactUri, @@ -1369,46 +1637,20 @@ func (suite *CoreTestSuite) TestCreateModelArtifact() { }, }, }, - } - - createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) + }, &modelVersionId) suite.Nilf(err, "error creating new model artifact for %d", modelVersionId) state, _ := openapi.NewArtifactStateFromValue(artifactState) - suite.NotNil(createdArtifact.Id, "created artifact id should not be nil") - suite.Equal(artifactName, *createdArtifact.Name) - suite.Equal(*state, *createdArtifact.State) - suite.Equal(artifactUri, *createdArtifact.Uri) - suite.Equal(artifactDescription, *createdArtifact.Description) - suite.Equal("onnx", *createdArtifact.ModelFormatName) - suite.Equal("1", *createdArtifact.ModelFormatVersion) - suite.Equal("aws-connection-models", *createdArtifact.StorageKey) - suite.Equal("bucket", *createdArtifact.StoragePath) - suite.Equal(customString, *(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) - - createdArtifactId, _ := converter.StringToInt64(createdArtifact.Id) - getById, err := suite.mlmdClient.GetArtifactsByID(context.Background(), &proto.GetArtifactsByIDRequest{ - ArtifactIds: []int64{*createdArtifactId}, - }) - suite.Nilf(err, "error getting model artifact by id %d", createdArtifactId) - - suite.Equal(*createdArtifactId, *getById.Artifacts[0].Id) - suite.Equal(fmt.Sprintf("%s:%s", modelVersionId, *createdArtifact.Name), *getById.Artifacts[0].Name) - suite.Equal(string(*createdArtifact.State), getById.Artifacts[0].State.String()) - suite.Equal(*createdArtifact.Uri, *getById.Artifacts[0].Uri) - suite.Equal(*createdArtifact.Description, getById.Artifacts[0].Properties["description"].GetStringValue()) - suite.Equal(*createdArtifact.ModelFormatName, getById.Artifacts[0].Properties["model_format_name"].GetStringValue()) - suite.Equal(*createdArtifact.ModelFormatVersion, getById.Artifacts[0].Properties["model_format_version"].GetStringValue()) - suite.Equal(*createdArtifact.StorageKey, getById.Artifacts[0].Properties["storage_key"].GetStringValue()) - suite.Equal(*createdArtifact.StoragePath, getById.Artifacts[0].Properties["storage_path"].GetStringValue()) - suite.Equal(*(*createdArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue, getById.Artifacts[0].CustomProperties["custom_string_prop"].GetStringValue()) - - modelVersionIdAsInt, _ := converter.StringToInt64(&modelVersionId) - byCtx, _ := suite.mlmdClient.GetArtifactsByContext(context.Background(), &proto.GetArtifactsByContextRequest{ - ContextId: (*int64)(modelVersionIdAsInt), - }) - suite.Equal(1, len(byCtx.Artifacts)) - suite.Equal(*createdArtifactId, *byCtx.Artifacts[0].Id) + suite.NotNil(modelArtifact.Id, "created artifact id should not be nil") + suite.Equal(artifactName, *modelArtifact.Name) + suite.Equal(*state, *modelArtifact.State) + suite.Equal(artifactUri, *modelArtifact.Uri) + suite.Equal(artifactDescription, *modelArtifact.Description) + suite.Equal("onnx", *modelArtifact.ModelFormatName) + suite.Equal("1", *modelArtifact.ModelFormatVersion) + suite.Equal("aws-connection-models", *modelArtifact.StorageKey) + suite.Equal("bucket", *modelArtifact.StoragePath) + suite.Equal(customString, *(*modelArtifact.CustomProperties)["custom_string_prop"].MetadataStringValue.StringValue) } func (suite *CoreTestSuite) TestCreateModelArtifactFailure() { @@ -1432,7 +1674,7 @@ func (suite *CoreTestSuite) TestCreateModelArtifactFailure() { _, err := service.UpsertModelArtifact(modelArtifact, nil) suite.NotNil(err) - suite.Equal("missing model version id, cannot create model artifact without model version", err.Error()) + suite.Equal("missing model version id, cannot create artifact without model version", err.Error()) _, err = service.UpsertModelArtifact(modelArtifact, &modelVersionId) suite.NotNil(err) @@ -1504,17 +1746,6 @@ func (suite *CoreTestSuite) TestUpdateModelArtifactFailure() { createdArtifact, err := service.UpsertModelArtifact(modelArtifact, &modelVersionId) suite.Nilf(err, "error creating new model artifact for model version %s", modelVersionId) suite.NotNilf(createdArtifact.Id, "created model artifact should not have nil Id") - - newState := "MARKED_FOR_DELETION" - createdArtifact.State = (*openapi.ArtifactState)(&newState) - updatedArtifact, err := service.UpsertModelArtifact(createdArtifact, &modelVersionId) - suite.Nilf(err, "error updating model artifact for %d: %v", modelVersionId, err) - - wrongId := "9998" - updatedArtifact.Id = &wrongId - _, err = service.UpsertModelArtifact(updatedArtifact, &modelVersionId) - suite.NotNil(err) - suite.Equal(fmt.Sprintf("no model artifact found for id %s", wrongId), err.Error()) } func (suite *CoreTestSuite) TestGetModelArtifactById() { diff --git a/pkg/openapi/.openapi-generator/FILES b/pkg/openapi/.openapi-generator/FILES index 6f119555..ba72484a 100644 --- a/pkg/openapi/.openapi-generator/FILES +++ b/pkg/openapi/.openapi-generator/FILES @@ -14,6 +14,7 @@ model_base_resource.go model_base_resource_create.go model_base_resource_list.go model_base_resource_update.go +model_doc_artifact.go model_error.go model_execution_state.go model_inference_service.go diff --git a/pkg/openapi/api_model_registry_service.go b/pkg/openapi/api_model_registry_service.go index 91826b6e..087ce1e6 100644 --- a/pkg/openapi/api_model_registry_service.go +++ b/pkg/openapi/api_model_registry_service.go @@ -3682,9 +3682,7 @@ func (r ApiGetModelVersionArtifactsRequest) Execute() (*ArtifactList, *http.Resp } /* -GetModelVersionArtifacts List All ModelVersion's artifacts - -Gets a list of all `Artifact` entities for the `ModelVersion`. +GetModelVersionArtifacts List all artifacts associated with the `ModelVersion` @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). @param modelversionId A unique identifier for a `ModelVersion`. diff --git a/pkg/openapi/model_artifact.go b/pkg/openapi/model_artifact.go index 43b8f85b..143a29c8 100644 --- a/pkg/openapi/model_artifact.go +++ b/pkg/openapi/model_artifact.go @@ -17,9 +17,17 @@ import ( // Artifact - A metadata Artifact Entity. type Artifact struct { + DocArtifact *DocArtifact ModelArtifact *ModelArtifact } +// DocArtifactAsArtifact is a convenience function that returns DocArtifact wrapped in Artifact +func DocArtifactAsArtifact(v *DocArtifact) Artifact { + return Artifact{ + DocArtifact: v, + } +} + // ModelArtifactAsArtifact is a convenience function that returns ModelArtifact wrapped in Artifact func ModelArtifactAsArtifact(v *ModelArtifact) Artifact { return Artifact{ @@ -37,6 +45,18 @@ func (dst *Artifact) UnmarshalJSON(data []byte) error { return fmt.Errorf("failed to unmarshal JSON into map for the discriminator lookup") } + // check if the discriminator value is 'DocArtifact' + if jsonDict["artifactType"] == "DocArtifact" { + // try to unmarshal JSON data into DocArtifact + err = json.Unmarshal(data, &dst.DocArtifact) + if err == nil { + return nil // data stored in dst.DocArtifact, return on the first match + } else { + dst.DocArtifact = nil + return fmt.Errorf("failed to unmarshal Artifact as DocArtifact: %s", err.Error()) + } + } + // check if the discriminator value is 'ModelArtifact' if jsonDict["artifactType"] == "ModelArtifact" { // try to unmarshal JSON data into ModelArtifact @@ -49,6 +69,18 @@ func (dst *Artifact) UnmarshalJSON(data []byte) error { } } + // check if the discriminator value is 'doc-artifact' + if jsonDict["artifactType"] == "doc-artifact" { + // try to unmarshal JSON data into DocArtifact + err = json.Unmarshal(data, &dst.DocArtifact) + if err == nil { + return nil // data stored in dst.DocArtifact, return on the first match + } else { + dst.DocArtifact = nil + return fmt.Errorf("failed to unmarshal Artifact as DocArtifact: %s", err.Error()) + } + } + // check if the discriminator value is 'model-artifact' if jsonDict["artifactType"] == "model-artifact" { // try to unmarshal JSON data into ModelArtifact @@ -66,6 +98,10 @@ func (dst *Artifact) UnmarshalJSON(data []byte) error { // Marshal data from the first non-nil pointers in the struct to JSON func (src Artifact) MarshalJSON() ([]byte, error) { + if src.DocArtifact != nil { + return json.Marshal(&src.DocArtifact) + } + if src.ModelArtifact != nil { return json.Marshal(&src.ModelArtifact) } @@ -78,6 +114,10 @@ func (obj *Artifact) GetActualInstance() interface{} { if obj == nil { return nil } + if obj.DocArtifact != nil { + return obj.DocArtifact + } + if obj.ModelArtifact != nil { return obj.ModelArtifact } diff --git a/pkg/openapi/model_doc_artifact.go b/pkg/openapi/model_doc_artifact.go new file mode 100644 index 00000000..28e36697 --- /dev/null +++ b/pkg/openapi/model_doc_artifact.go @@ -0,0 +1,453 @@ +/* +Model Registry REST API + +REST API for Model Registry to create and manage ML model metadata + +API version: v1alpha1 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package openapi + +import ( + "encoding/json" +) + +// checks if the DocArtifact type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &DocArtifact{} + +// DocArtifact A document. +type DocArtifact struct { + // User provided custom properties which are not defined by its type. + CustomProperties *map[string]MetadataValue `json:"customProperties,omitempty"` + // An optional description about the resource. + Description *string `json:"description,omitempty"` + // The external id that come from the clients’ system. This field is optional. If set, it must be unique among all resources within a database instance. + ExternalID *string `json:"externalID,omitempty"` + // The uniform resource identifier of the physical artifact. May be empty if there is no physical artifact. + Uri *string `json:"uri,omitempty"` + State *ArtifactState `json:"state,omitempty"` + // The client provided name of the artifact. This field is optional. If set, it must be unique among all the artifacts of the same artifact type within a database instance and cannot be changed once set. + Name *string `json:"name,omitempty"` + // Output only. The unique server generated id of the resource. + Id *string `json:"id,omitempty"` + // Output only. Create time of the resource in millisecond since epoch. + CreateTimeSinceEpoch *string `json:"createTimeSinceEpoch,omitempty"` + // Output only. Last update time of the resource since epoch in millisecond since epoch. + LastUpdateTimeSinceEpoch *string `json:"lastUpdateTimeSinceEpoch,omitempty"` + ArtifactType string `json:"artifactType"` +} + +// NewDocArtifact instantiates a new DocArtifact object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewDocArtifact(artifactType string) *DocArtifact { + this := DocArtifact{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + this.ArtifactType = artifactType + return &this +} + +// NewDocArtifactWithDefaults instantiates a new DocArtifact object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewDocArtifactWithDefaults() *DocArtifact { + this := DocArtifact{} + var state ArtifactState = ARTIFACTSTATE_UNKNOWN + this.State = &state + var artifactType string = "doc-artifact" + this.ArtifactType = artifactType + return &this +} + +// GetCustomProperties returns the CustomProperties field value if set, zero value otherwise. +func (o *DocArtifact) GetCustomProperties() map[string]MetadataValue { + if o == nil || IsNil(o.CustomProperties) { + var ret map[string]MetadataValue + return ret + } + return *o.CustomProperties +} + +// GetCustomPropertiesOk returns a tuple with the CustomProperties field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetCustomPropertiesOk() (*map[string]MetadataValue, bool) { + if o == nil || IsNil(o.CustomProperties) { + return nil, false + } + return o.CustomProperties, true +} + +// HasCustomProperties returns a boolean if a field has been set. +func (o *DocArtifact) HasCustomProperties() bool { + if o != nil && !IsNil(o.CustomProperties) { + return true + } + + return false +} + +// SetCustomProperties gets a reference to the given map[string]MetadataValue and assigns it to the CustomProperties field. +func (o *DocArtifact) SetCustomProperties(v map[string]MetadataValue) { + o.CustomProperties = &v +} + +// GetDescription returns the Description field value if set, zero value otherwise. +func (o *DocArtifact) GetDescription() string { + if o == nil || IsNil(o.Description) { + var ret string + return ret + } + return *o.Description +} + +// GetDescriptionOk returns a tuple with the Description field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetDescriptionOk() (*string, bool) { + if o == nil || IsNil(o.Description) { + return nil, false + } + return o.Description, true +} + +// HasDescription returns a boolean if a field has been set. +func (o *DocArtifact) HasDescription() bool { + if o != nil && !IsNil(o.Description) { + return true + } + + return false +} + +// SetDescription gets a reference to the given string and assigns it to the Description field. +func (o *DocArtifact) SetDescription(v string) { + o.Description = &v +} + +// GetExternalID returns the ExternalID field value if set, zero value otherwise. +func (o *DocArtifact) GetExternalID() string { + if o == nil || IsNil(o.ExternalID) { + var ret string + return ret + } + return *o.ExternalID +} + +// GetExternalIDOk returns a tuple with the ExternalID field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetExternalIDOk() (*string, bool) { + if o == nil || IsNil(o.ExternalID) { + return nil, false + } + return o.ExternalID, true +} + +// HasExternalID returns a boolean if a field has been set. +func (o *DocArtifact) HasExternalID() bool { + if o != nil && !IsNil(o.ExternalID) { + return true + } + + return false +} + +// SetExternalID gets a reference to the given string and assigns it to the ExternalID field. +func (o *DocArtifact) SetExternalID(v string) { + o.ExternalID = &v +} + +// GetUri returns the Uri field value if set, zero value otherwise. +func (o *DocArtifact) GetUri() string { + if o == nil || IsNil(o.Uri) { + var ret string + return ret + } + return *o.Uri +} + +// GetUriOk returns a tuple with the Uri field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetUriOk() (*string, bool) { + if o == nil || IsNil(o.Uri) { + return nil, false + } + return o.Uri, true +} + +// HasUri returns a boolean if a field has been set. +func (o *DocArtifact) HasUri() bool { + if o != nil && !IsNil(o.Uri) { + return true + } + + return false +} + +// SetUri gets a reference to the given string and assigns it to the Uri field. +func (o *DocArtifact) SetUri(v string) { + o.Uri = &v +} + +// GetState returns the State field value if set, zero value otherwise. +func (o *DocArtifact) GetState() ArtifactState { + if o == nil || IsNil(o.State) { + var ret ArtifactState + return ret + } + return *o.State +} + +// GetStateOk returns a tuple with the State field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetStateOk() (*ArtifactState, bool) { + if o == nil || IsNil(o.State) { + return nil, false + } + return o.State, true +} + +// HasState returns a boolean if a field has been set. +func (o *DocArtifact) HasState() bool { + if o != nil && !IsNil(o.State) { + return true + } + + return false +} + +// SetState gets a reference to the given ArtifactState and assigns it to the State field. +func (o *DocArtifact) SetState(v ArtifactState) { + o.State = &v +} + +// GetName returns the Name field value if set, zero value otherwise. +func (o *DocArtifact) GetName() string { + if o == nil || IsNil(o.Name) { + var ret string + return ret + } + return *o.Name +} + +// GetNameOk returns a tuple with the Name field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetNameOk() (*string, bool) { + if o == nil || IsNil(o.Name) { + return nil, false + } + return o.Name, true +} + +// HasName returns a boolean if a field has been set. +func (o *DocArtifact) HasName() bool { + if o != nil && !IsNil(o.Name) { + return true + } + + return false +} + +// SetName gets a reference to the given string and assigns it to the Name field. +func (o *DocArtifact) SetName(v string) { + o.Name = &v +} + +// GetId returns the Id field value if set, zero value otherwise. +func (o *DocArtifact) GetId() string { + if o == nil || IsNil(o.Id) { + var ret string + return ret + } + return *o.Id +} + +// GetIdOk returns a tuple with the Id field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetIdOk() (*string, bool) { + if o == nil || IsNil(o.Id) { + return nil, false + } + return o.Id, true +} + +// HasId returns a boolean if a field has been set. +func (o *DocArtifact) HasId() bool { + if o != nil && !IsNil(o.Id) { + return true + } + + return false +} + +// SetId gets a reference to the given string and assigns it to the Id field. +func (o *DocArtifact) SetId(v string) { + o.Id = &v +} + +// GetCreateTimeSinceEpoch returns the CreateTimeSinceEpoch field value if set, zero value otherwise. +func (o *DocArtifact) GetCreateTimeSinceEpoch() string { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + var ret string + return ret + } + return *o.CreateTimeSinceEpoch +} + +// GetCreateTimeSinceEpochOk returns a tuple with the CreateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetCreateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.CreateTimeSinceEpoch) { + return nil, false + } + return o.CreateTimeSinceEpoch, true +} + +// HasCreateTimeSinceEpoch returns a boolean if a field has been set. +func (o *DocArtifact) HasCreateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.CreateTimeSinceEpoch) { + return true + } + + return false +} + +// SetCreateTimeSinceEpoch gets a reference to the given string and assigns it to the CreateTimeSinceEpoch field. +func (o *DocArtifact) SetCreateTimeSinceEpoch(v string) { + o.CreateTimeSinceEpoch = &v +} + +// GetLastUpdateTimeSinceEpoch returns the LastUpdateTimeSinceEpoch field value if set, zero value otherwise. +func (o *DocArtifact) GetLastUpdateTimeSinceEpoch() string { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + var ret string + return ret + } + return *o.LastUpdateTimeSinceEpoch +} + +// GetLastUpdateTimeSinceEpochOk returns a tuple with the LastUpdateTimeSinceEpoch field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetLastUpdateTimeSinceEpochOk() (*string, bool) { + if o == nil || IsNil(o.LastUpdateTimeSinceEpoch) { + return nil, false + } + return o.LastUpdateTimeSinceEpoch, true +} + +// HasLastUpdateTimeSinceEpoch returns a boolean if a field has been set. +func (o *DocArtifact) HasLastUpdateTimeSinceEpoch() bool { + if o != nil && !IsNil(o.LastUpdateTimeSinceEpoch) { + return true + } + + return false +} + +// SetLastUpdateTimeSinceEpoch gets a reference to the given string and assigns it to the LastUpdateTimeSinceEpoch field. +func (o *DocArtifact) SetLastUpdateTimeSinceEpoch(v string) { + o.LastUpdateTimeSinceEpoch = &v +} + +// GetArtifactType returns the ArtifactType field value +func (o *DocArtifact) GetArtifactType() string { + if o == nil { + var ret string + return ret + } + + return o.ArtifactType +} + +// GetArtifactTypeOk returns a tuple with the ArtifactType field value +// and a boolean to check if the value has been set. +func (o *DocArtifact) GetArtifactTypeOk() (*string, bool) { + if o == nil { + return nil, false + } + return &o.ArtifactType, true +} + +// SetArtifactType sets field value +func (o *DocArtifact) SetArtifactType(v string) { + o.ArtifactType = v +} + +func (o DocArtifact) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o DocArtifact) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.CustomProperties) { + toSerialize["customProperties"] = o.CustomProperties + } + if !IsNil(o.Description) { + toSerialize["description"] = o.Description + } + if !IsNil(o.ExternalID) { + toSerialize["externalID"] = o.ExternalID + } + if !IsNil(o.Uri) { + toSerialize["uri"] = o.Uri + } + if !IsNil(o.State) { + toSerialize["state"] = o.State + } + if !IsNil(o.Name) { + toSerialize["name"] = o.Name + } + if !IsNil(o.Id) { + toSerialize["id"] = o.Id + } + if !IsNil(o.CreateTimeSinceEpoch) { + toSerialize["createTimeSinceEpoch"] = o.CreateTimeSinceEpoch + } + if !IsNil(o.LastUpdateTimeSinceEpoch) { + toSerialize["lastUpdateTimeSinceEpoch"] = o.LastUpdateTimeSinceEpoch + } + toSerialize["artifactType"] = o.ArtifactType + return toSerialize, nil +} + +type NullableDocArtifact struct { + value *DocArtifact + isSet bool +} + +func (v NullableDocArtifact) Get() *DocArtifact { + return v.value +} + +func (v *NullableDocArtifact) Set(val *DocArtifact) { + v.value = val + v.isSet = true +} + +func (v NullableDocArtifact) IsSet() bool { + return v.isSet +} + +func (v *NullableDocArtifact) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableDocArtifact(val *DocArtifact) *NullableDocArtifact { + return &NullableDocArtifact{value: val, isSet: true} +} + +func (v NullableDocArtifact) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableDocArtifact) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} From 79492e8b9637c8cb569e59dce799ede1c74d04a3 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Fri, 9 Feb 2024 13:42:21 +0100 Subject: [PATCH 240/254] add RobotFramework for doc-artifact REST test --- test/robot/MRkeywords.resource | 26 ++++++++++++++++++++++++++ test/robot/Setup.resource | 3 +++ test/robot/UserStory.robot | 19 +++++++++++++++++++ test/robot/data.yaml | 4 ++++ 4 files changed, 52 insertions(+) diff --git a/test/robot/MRkeywords.resource b/test/robot/MRkeywords.resource index 6c26fcbe..1f66bf64 100644 --- a/test/robot/MRkeywords.resource +++ b/test/robot/MRkeywords.resource @@ -95,6 +95,19 @@ I create a child ModelArtifact RETURN ${result} +I create a child Artifact + [Arguments] ${modelversionId} ${payload} + IF $MODE == "REST" + ${resp}= POST url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_versions/${modelversionId}/artifacts json=&{payload} expected_status=201 + Log to console ${resp.json()} + ${result} Set Variable ${resp.json()['id']} + ELSE + Log to console ${MODE} + Fail Not Implemented + END + RETURN ${result} + + I get RegisteredModelByID [Arguments] ${id} IF $MODE == "REST" @@ -132,3 +145,16 @@ I get ModelArtifactByID Fail Not Implemented END RETURN ${result} + + +I get ArtifactsByModelVersionID + [Arguments] ${id} + IF $MODE == "REST" + ${resp}= GET url=http://${MR_HOST}:8080/api/model_registry/v1alpha1/model_versions/${id}/artifacts expected_status=200 + ${result} Set Variable ${resp.json()} + Log to console ${resp.json()} + ELSE + Log to console ${MODE} + Fail Not Implemented + END + RETURN ${result} diff --git a/test/robot/Setup.resource b/test/robot/Setup.resource index 2d2905df..72e95682 100644 --- a/test/robot/Setup.resource +++ b/test/robot/Setup.resource @@ -17,10 +17,13 @@ Test Setup with dummy data Set Test Variable &model_version &{model_version} &{model_artifact} Get From Dictionary ${YAML} model_artifact Set Test Variable &model_artifact &{model_artifact} + &{doc_artifact} Get From Dictionary ${YAML} doc_artifact + Set Test Variable &doc_artifact &{doc_artifact} *** Variables *** &{registered_model} &{model_version} &{model_artifact} +&{doc_artifact} ${name} diff --git a/test/robot/UserStory.robot b/test/robot/UserStory.robot index 646d6147..4fa234c5 100644 --- a/test/robot/UserStory.robot +++ b/test/robot/UserStory.robot @@ -33,3 +33,22 @@ As a MLOps engineer I would like to store a description of the model And Should be equal ${r["description"]} consectetur adipiscing elit ${r} Then I get ModelArtifactByID id=${aId} And Should be equal ${r["description"]} sed do eiusmod tempor incididunt + +As a MLOps engineer I would like to store a longer documentation for the model + Set To Dictionary ${registered_model} description=Lorem ipsum dolor sit amet name=${name} + Set To Dictionary ${model_version} description=consectetur adipiscing elit + Set To Dictionary ${model_artifact} description=sed do eiusmod tempor incididunt + Set To Dictionary ${doc_artifact} uri="https://README.md" + ${rId} Given I create a RegisteredModel payload=${registered_model} + ${vId} And I create a child ModelVersion registeredModelID=${rId} payload=&{model_version} + ${aId} And I create a child ModelArtifact modelversionId=${vId} payload=&{model_artifact} + ${docId} And I create a child Artifact modelversionId=${vId} payload=&{doc_artifact} + ${r} Then I get RegisteredModelByID id=${rId} + And Should be equal ${r["description"]} Lorem ipsum dolor sit amet + ${r} Then I get ModelVersionByID id=${vId} + And Should be equal ${r["description"]} consectetur adipiscing elit + ${r} Then I get ModelArtifactByID id=${aId} + And Should be equal ${r["description"]} sed do eiusmod tempor incididunt + ${r} Then I get ArtifactsByModelVersionID id=${vId} + ${cnt} Then Get length ${r["items"]} + And Should Be Equal As Integers ${cnt} 2 diff --git a/test/robot/data.yaml b/test/robot/data.yaml index 3de590e7..12b35828 100644 --- a/test/robot/data.yaml +++ b/test/robot/data.yaml @@ -7,3 +7,7 @@ model_artifact: artifactType: model-artifact name: ModelArtifactName uri: s3://12345 +doc_artifact: + artifactType: doc-artifact + name: README + uri: s3://README From 4708b34788079cc8a98e98239bd53d049a76615c Mon Sep 17 00:00:00 2001 From: tarilabs Date: Fri, 9 Feb 2024 11:31:51 +0100 Subject: [PATCH 241/254] add Homepage, Issues on pyproject.toml for PyPI --- clients/python/pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index 656792f6..bafe1b37 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -6,6 +6,10 @@ authors = ["Isabella Basso do Amaral "] license = "Apache-2.0" readme = "README.md" +[project.urls] +Homepage = "https://github.com/opendatahub-io/model-registry" +Issues = "https://github.com/opendatahub-io/model-registry/issues" + [tool.poetry.dependencies] python = ">= 3.9, < 3.11" attrs = "^21.0" From 901f8745b35fd777c2886b501955443c4247730e Mon Sep 17 00:00:00 2001 From: tarilabs Date: Fri, 9 Feb 2024 18:30:28 +0100 Subject: [PATCH 242/254] apply poetry conventions in pyproject.toml --- clients/python/pyproject.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clients/python/pyproject.toml b/clients/python/pyproject.toml index bafe1b37..56988c69 100644 --- a/clients/python/pyproject.toml +++ b/clients/python/pyproject.toml @@ -5,10 +5,10 @@ description = "Client for Red Hat OpenDataHub Model Registry" authors = ["Isabella Basso do Amaral "] license = "Apache-2.0" readme = "README.md" +homepage = "https://github.com/opendatahub-io/model-registry" -[project.urls] -Homepage = "https://github.com/opendatahub-io/model-registry" -Issues = "https://github.com/opendatahub-io/model-registry/issues" +[tool.poetry.urls] +"Issues" = "https://github.com/opendatahub-io/model-registry/issues" [tool.poetry.dependencies] python = ">= 3.9, < 3.11" From 921b05e7776224cca15afc04d4d0c524bbc35938 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Mon, 12 Feb 2024 10:09:00 +0100 Subject: [PATCH 243/254] add Shell script openshift-ci make some REST call to MR (#295) * add Shell script openshift-ci make some REST call to MR In the scope of testing of Model Registry in openshift-ci: - make a Shell script which invokes some REST calls to MR, - so to make sure the REST endpoint is responsive, - then create a K8s ISVC on the cluster, - and display the MR InferenceService entities. Later, in a subsequent issue/PR, once: opendatahub-io/odh-model-controller#135 is merged, the last bulletpoint can be automated and placed under test in the final part of this script so to make sure the K8s ISVC on the cluster reflected as a precise MR InferenceService entity. * omit OCP_CLUSTER_NAME to be valorized once on openshift-ci --- test/scripts/rest.sh | 97 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100755 test/scripts/rest.sh diff --git a/test/scripts/rest.sh b/test/scripts/rest.sh new file mode 100755 index 00000000..d7cfa8b3 --- /dev/null +++ b/test/scripts/rest.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +make_post_extract_id() { + local url="$1" + local data="$2" + local id=$(curl -s -X POST "$url" \ + -H 'accept: application/json' \ + -H 'Content-Type: application/json' \ + -d "$data" | jq -r '.id') + + if [ -z "$id" ]; then + echo "Error: Failed to extract ID from response" + exit 1 + fi + + echo "$id" +} + +# TODO: finalize using openshift-ci values. +OCP_CLUSTER_NAME="PROVIDE OCP CLUSTER NAME FOR OPENSHIFT-CI" +MR_NAMESPACE="shared-modelregistry-ns" +MR_HOSTNAME="http://modelregistry-sample-http-$MR_NAMESPACE.apps.$OCP_CLUSTER_NAME" + +timestamp=$(date +"%Y%m%d%H%M%S") +rm_name="demo-$timestamp" + +rm_id=$(make_post_extract_id "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models" '{ + "description": "lorem ipsum registered model", + "name": "'"$rm_name"'" +}') + +if [ $? -ne 0 ]; then + exit 1 +fi +echo "Registered Model ID: $rm_id" + +mv_id=$(make_post_extract_id "$MR_HOSTNAME/api/model_registry/v1alpha1/model_versions" '{ + "description": "lorem ipsum model version", + "name": "v1", + "author": "John Doe", + "registeredModelID": "'"$rm_id"'" +}') + +if [ $? -ne 0 ]; then + exit 1 +fi +echo "Model Version ID: $mv_id" + +RAW_ML_MODEL_URI='https://huggingface.co/tarilabs/mnist/resolve/v1.nb20231206162408/mnist.onnx' +ma_id=$(make_post_extract_id "$MR_HOSTNAME/api/model_registry/v1alpha1/model_versions/$mv_id/artifacts" '{ + "description": "lorem ipsum model artifact", + "uri": "'"$RAW_ML_MODEL_URI"'", + "name": "mnist", + "modelFormatName": "onnx", + "modelFormatVersion": "1", + "storageKey": "aws-connection-unused", + "storagePath": "unused just demo", + "artifactType": "model-artifact" +}') + +if [ $? -ne 0 ]; then + exit 1 +fi +echo "Model Artifact ID: $ma_id" + +ISVC_TARGET_NS=odh-project-b +MODEL_SERVER_NAME=modelserverb + +oc apply -n $ISVC_TARGET_NS -f - < Date: Mon, 12 Feb 2024 20:07:41 +0100 Subject: [PATCH 244/254] build(deps): bump helm/kind-action from 1.8.0 to 1.9.0 (#300) Bumps [helm/kind-action](https://github.com/helm/kind-action) from 1.8.0 to 1.9.0. - [Release notes](https://github.com/helm/kind-action/releases) - [Commits](https://github.com/helm/kind-action/compare/v1.8.0...v1.9.0) --- updated-dependencies: - dependency-name: helm/kind-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-image-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index 98f5de1f..ce4b2e7f 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -32,7 +32,7 @@ jobs: VERSION: ${{ steps.tags.outputs.tag }} run: ./scripts/build_deploy.sh - name: Start Kind Cluster - uses: helm/kind-action@v1.8.0 + uses: helm/kind-action@v1.9.0 - name: Load Local Registry Test Image env: IMG: "quay.io/opendatahub/model-registry:${{ steps.tags.outputs.tag }}" From 3a382639e07e3edec8416175a53baea3743913e8 Mon Sep 17 00:00:00 2001 From: tarilabs Date: Tue, 13 Feb 2024 13:43:01 +0100 Subject: [PATCH 245/254] remove test_hf_import_missing_author test --- clients/python/tests/test_client.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index a88f8d07..7dee53ca 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -83,20 +83,3 @@ def test_hf_import(mr_client: ModelRegistry): ) assert mr_client.get_model_version(name, version) assert mr_client.get_model_artifact(name, version) - - -def test_hf_import_missing_author(mr_client: ModelRegistry): - pytest.importorskip("huggingface_hub") - name = "bert-base-uncased" - version = "1.2.3" - - with pytest.warns(match=r".*author is unknown.*"): - assert mr_client.register_hf_model( - name, - "model.onnx", - version=version, - model_format_name="test format", - model_format_version="test version", - ) - assert (mv := mr_client.get_model_version(name, version)) - assert mv.author == "unknown" From dbcacad3c6dda9be0b2aeb0afac21bda388d711b Mon Sep 17 00:00:00 2001 From: Tony Davidson Date: Tue, 13 Feb 2024 15:15:34 +0000 Subject: [PATCH 246/254] Creating OWNERS file needed for openshift-ci (#302) Adding tonyxrmdavidson to OWNERS file --- OWNERS | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 OWNERS diff --git a/OWNERS b/OWNERS new file mode 100644 index 00000000..2ff7cbf4 --- /dev/null +++ b/OWNERS @@ -0,0 +1,25 @@ +# DO NOT EDIT; this file is auto-generated using https://github.com/openshift/ci-tools. +# Fetched from https://github.com/opendatahub-io/codeflare-operator root OWNERS +# If the repo had OWNERS_ALIASES then the aliases were expanded +# Logins who are not members of 'openshift' organization were filtered out +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md + +approvers: +- dhirajsb +- isinyaaa +- lampajr +- nehachopra27 +- rareddy +- rkubis +- tarilabs +- tonyxrmdavidson +options: {} +reviewers: +- dhirajsb +- isinyaaa +- lampajr +- nehachopra27 +- rareddy +- rkubis +- tarilabs +- tonyxrmdavidson From 90f7ddcd8d52274e7e9f9e2c805d4bc6bdad5b47 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 15 Feb 2024 11:17:29 +0100 Subject: [PATCH 247/254] Automate openapi server generation (#308) * Fix type_assert.patch * Improve openapi-server generation * Automate openapi server generation if something changed --- .pre-commit-config.yaml | 2 + Dockerfile | 3 + Makefile | 18 +- .../openapi/api_model_registry_service.go | 5 +- internal/server/openapi/type_asserts.go | 19 + patches/type_asserts.patch | 5 +- scripts/gen_openapi_server.sh | 22 + templates/go-server/controller-api.mustache | 450 ++++++++++++++++++ 8 files changed, 511 insertions(+), 13 deletions(-) create mode 100755 scripts/gen_openapi_server.sh create mode 100644 templates/go-server/controller-api.mustache diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b40ec072..783a3b43 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,3 +1,5 @@ + +exclude: '^patches/' repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 diff --git a/Dockerfile b/Dockerfile index 93f0143b..e12191d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,6 +34,9 @@ COPY cmd/ cmd/ COPY api/ api/ COPY internal/ internal/ COPY pkg/ pkg/ +COPY scripts/ scripts/ +COPY patches/ patches/ +COPY templates/ templates/ # Build USER root diff --git a/Makefile b/Makefile index 4e59ae60..e99a021d 100644 --- a/Makefile +++ b/Makefile @@ -67,18 +67,18 @@ gen/converter: gen/grpc internal/converter/generated/converter.go # validate the openapi schema .PHONY: openapi/validate openapi/validate: bin/openapi-generator-cli - openapi-generator-cli validate -i api/openapi/model-registry.yaml + @openapi-generator-cli validate -i api/openapi/model-registry.yaml # generate the openapi server implementation -# note: run manually only when model-registry.yaml api changes, for model changes gen/openapi is run automatically .PHONY: gen/openapi-server gen/openapi-server: bin/openapi-generator-cli openapi/validate - openapi-generator-cli generate \ - -i api/openapi/model-registry.yaml -g go-server -o internal/server/openapi --package-name openapi --global-property models \ - --ignore-file-override ./.openapi-generator-ignore --additional-properties=outputAsLibrary=true,enumClassPrefix=true,router=chi,sourceFolder=,onlyInterfaces=true,isGoSubmodule=true,enumClassPrefix=true,useOneOfDiscriminatorLookup=true \ - --template-dir ./templates/go-server - ./scripts/gen_type_asserts.sh - gofmt -w internal/server/openapi + @if git diff --cached --name-only | grep -q "api/openapi/model-registry.yaml" || \ + git diff --name-only | grep -q "api/openapi/model-registry.yaml" || \ + [ -n "${FORCE_SERVER_GENERATION}" ]; then \ + ROOT_FOLDER="." ./scripts/gen_openapi_server.sh; \ + else \ + echo "INFO api/openapi/model-registry.yaml is not staged or modified, will not re-generate server"; \ + fi # generate the openapi schema model and client .PHONY: gen/openapi @@ -156,7 +156,7 @@ build/odh: vet go build .PHONY: gen -gen: deps gen/grpc gen/openapi gen/converter +gen: deps gen/grpc gen/openapi gen/openapi-server gen/converter go generate ./... .PHONY: lint diff --git a/internal/server/openapi/api_model_registry_service.go b/internal/server/openapi/api_model_registry_service.go index e079b090..62990ee9 100644 --- a/internal/server/openapi/api_model_registry_service.go +++ b/internal/server/openapi/api_model_registry_service.go @@ -3,7 +3,7 @@ * * REST API for Model Registry to create and manage ML model metadata * - * API version: 1.0.0 + * API version: v1alpha1 * Generated by: OpenAPI Generator (https://openapi-generator.tech) */ @@ -15,6 +15,7 @@ import ( "strings" "github.com/go-chi/chi/v5" + model "github.com/opendatahub-io/model-registry/pkg/openapi" ) @@ -692,7 +693,7 @@ func (c *ModelRegistryServiceAPIController) GetModelVersion(w http.ResponseWrite EncodeJSONResponse(result.Body, &result.Code, w) } -// GetModelVersionArtifacts - List All ModelVersion's artifacts +// GetModelVersionArtifacts - List all artifacts associated with the `ModelVersion` func (c *ModelRegistryServiceAPIController) GetModelVersionArtifacts(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() modelversionIdParam := chi.URLParam(r, "modelversionId") diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go index 38ed51dd..6d08bbb2 100644 --- a/internal/server/openapi/type_asserts.go +++ b/internal/server/openapi/type_asserts.go @@ -191,6 +191,25 @@ func AssertBaseResourceUpdateConstraints(obj model.BaseResourceUpdate) error { return nil } +// AssertDocArtifactRequired checks if the required fields are not zero-ed +func AssertDocArtifactRequired(obj model.DocArtifact) error { + elements := map[string]interface{}{ + "artifactType": obj.ArtifactType, + } + for name, el := range elements { + if isZero := IsZeroValue(el); isZero { + return &RequiredError{Field: name} + } + } + + return nil +} + +// AssertDocArtifactConstraints checks if the values respects the defined constraints +func AssertDocArtifactConstraints(obj model.DocArtifact) error { + return nil +} + // AssertErrorRequired checks if the required fields are not zero-ed func AssertErrorRequired(obj model.Error) error { elements := map[string]interface{}{ diff --git a/patches/type_asserts.patch b/patches/type_asserts.patch index 8735b1c2..c7e5d946 100644 --- a/patches/type_asserts.patch +++ b/patches/type_asserts.patch @@ -1,9 +1,9 @@ diff --git a/internal/server/openapi/type_asserts.go b/internal/server/openapi/type_asserts.go -index 4318f15..2aba64a 100644 +index 6e8ecb1..6d08bbb 100644 --- a/internal/server/openapi/type_asserts.go +++ b/internal/server/openapi/type_asserts.go @@ -18,15 +18,15 @@ import ( - + // AssertArtifactRequired checks if the required fields are not zero-ed func AssertArtifactRequired(obj model.Artifact) error { - elements := map[string]interface{}{ @@ -26,3 +26,4 @@ index 4318f15..2aba64a 100644 + // } return nil } + diff --git a/scripts/gen_openapi_server.sh b/scripts/gen_openapi_server.sh new file mode 100755 index 00000000..6bac6684 --- /dev/null +++ b/scripts/gen_openapi_server.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +echo "Generating the OpenAPI server" + +ROOT_FOLDER="${ROOT_FOLDER:-..}" + +openapi-generator-cli generate \ + -i $ROOT_FOLDER/api/openapi/model-registry.yaml -g go-server -o $ROOT_FOLDER/internal/server/openapi --package-name openapi --global-property models,apis \ + --ignore-file-override $ROOT_FOLDER/.openapi-generator-ignore --additional-properties=outputAsLibrary=true,enumClassPrefix=true,router=chi,sourceFolder=,onlyInterfaces=true,isGoSubmodule=true,enumClassPrefix=true,useOneOfDiscriminatorLookup=true \ + --template-dir $ROOT_FOLDER/templates/go-server + +sed -i 's/, orderByParam/, model.OrderByField(orderByParam)/g' $ROOT_FOLDER/internal/server/openapi/api_model_registry_service.go +sed -i 's/, sortOrderParam/, model.SortOrder(sortOrderParam)/g' $ROOT_FOLDER/internal/server/openapi/api_model_registry_service.go + +echo "Assembling type_assert Go file" +./scripts/gen_type_asserts.sh + +gofmt -w $ROOT_FOLDER/internal/server/openapi + +echo "OpenAPI server generation completed" diff --git a/templates/go-server/controller-api.mustache b/templates/go-server/controller-api.mustache new file mode 100644 index 00000000..4735921a --- /dev/null +++ b/templates/go-server/controller-api.mustache @@ -0,0 +1,450 @@ +{{>partial_header}} +package {{packageName}} + +import ( + "encoding/json" + {{#isBodyParam}} + {{^required}} + "errors" + "io" + {{/required}} + {{/isBodyParam}} + "net/http" + "strings" + +{{#routers}} + {{#mux}} + "github.com/gorilla/mux" + {{/mux}} + {{#chi}} + "github.com/go-chi/chi/v5" + {{/chi}} + + model "github.com/opendatahub-io/model-registry/pkg/openapi" +{{/routers}} +) + +// {{classname}}Controller binds http requests to an api service and writes the service results to the http response +type {{classname}}Controller struct { + service {{classname}}Servicer + errorHandler ErrorHandler +} + +// {{classname}}Option for how the controller is set up. +type {{classname}}Option func(*{{classname}}Controller) + +// With{{classname}}ErrorHandler inject ErrorHandler into controller +func With{{classname}}ErrorHandler(h ErrorHandler) {{classname}}Option { + return func(c *{{classname}}Controller) { + c.errorHandler = h + } +} + +// New{{classname}}Controller creates a default api controller +func New{{classname}}Controller(s {{classname}}Servicer, opts ...{{classname}}Option) Router { + controller := &{{classname}}Controller{ + service: s, + errorHandler: DefaultErrorHandler, + } + + for _, opt := range opts { + opt(controller) + } + + return controller +} + +// Routes returns all the api routes for the {{classname}}Controller +func (c *{{classname}}Controller) Routes() Routes { + return Routes{ +{{#operations}} + {{#operation}} + "{{operationId}}": Route{ + strings.ToUpper("{{httpMethod}}"), + "{{{basePathWithoutHost}}}{{{path}}}", + c.{{operationId}}, + }, + {{/operation}} +{{/operations}} + } +}{{#operations}}{{#operation}} + +// {{nickname}} - {{{summary}}} +{{#isDeprecated}} +// Deprecated +{{/isDeprecated}} +func (c *{{classname}}Controller) {{nickname}}(w http.ResponseWriter, r *http.Request) { + {{#hasFormParams}} + {{#isMultipart}} + if err := r.ParseMultipartForm(32 << 20); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isMultipart}} + {{^isMultipart}} + if err := r.ParseForm(); err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isMultipart}} + {{/hasFormParams}} + {{#routers}} + {{#mux}} + {{#hasPathParams}} + params := mux.Vars(r) + {{/hasPathParams}} + {{/mux}} + {{/routers}} + {{#hasQueryParams}} + query := r.URL.Query() + {{/hasQueryParams}} + {{#allParams}} + {{#isPathParam}} + {{#isNumber}} + {{paramName}}Param, err := parseNumericParameter[float32]( + {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}} + WithDefaultOrParse[float32]({{defaultValue}}, parseFloat32),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[float32](parseFloat32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[float32](parseFloat32),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isNumber}} + {{#isFloat}} + {{paramName}}Param, err := parseNumericParameter[float32]( + {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}} + WithDefaultOrParse[float32]({{defaultValue}}, parseFloat32),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[float32](parseFloat32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[float32](parseFloat32),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isFloat}} + {{#isDouble}} + {{paramName}}Param, err := parseNumericParameter[float64]( + {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}} + WithDefaultOrParse[float64]({{defaultValue}}, parseFloat64),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[float64](parseFloat64),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[float64](parseFloat64),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[float64]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float64]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isDouble}} + {{#isLong}} + {{paramName}}Param, err := parseNumericParameter[int64]( + {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}} + WithDefaultOrParse[int64]({{defaultValue}}, parseInt64),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[int64](parseInt64),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[int64](parseInt64),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int64]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isLong}} + {{#isInteger}} + {{paramName}}Param, err := parseNumericParameter[int32]( + {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}},{{#defaultValue}} + WithDefaultOrParse[int32]({{defaultValue}}, parseInt32),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[int32](parseInt32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[int32](parseInt32),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isInteger}} + {{^isNumber}} + {{^isFloat}} + {{^isDouble}} + {{^isLong}} + {{^isInteger}} + {{paramName}}Param := {{#routers}}{{#mux}}params["{{baseName}}"]{{/mux}}{{#chi}}chi.URLParam(r, "{{baseName}}"){{/chi}}{{/routers}} + {{/isInteger}} + {{/isLong}} + {{/isDouble}} + {{/isFloat}} + {{/isNumber}} + {{/isPathParam}} + {{#isQueryParam}} + {{#isNumber}} + {{paramName}}Param, err := parseNumericParameter[float32]( + query.Get("{{baseName}}"),{{#defaultValue}} + WithDefaultOrParse[float32]({{defaultValue}}, parseFloat32),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[float32](parseFloat32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[float32](parseFloat32),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isNumber}} + {{#isFloat}} + {{paramName}}Param, err := parseNumericParameter[float32]( + query.Get("{{baseName}}"),{{#defaultValue}} + WithDefaultOrParse[float32]({{defaultValue}}, parseFloat32),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[float32](parseFloat32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[float32](parseFloat32),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isFloat}} + {{#isDouble}} + {{paramName}}Param, err := parseNumericParameter[float64]( + query.Get("{{baseName}}"),{{#defaultValue}} + WithDefaultOrParse[float64]({{defaultValue}}, parseFloat64),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[float64](parseFloat64),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[float64](parseFloat64),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[float64]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float64]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isDouble}} + {{#isLong}} + {{paramName}}Param, err := parseNumericParameter[int64]( + query.Get("{{baseName}}"),{{#defaultValue}} + WithDefaultOrParse[int64]({{defaultValue}}, parseInt64),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[int64](parseInt64),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[int64](parseInt64),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int64]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isLong}} + {{#isInteger}} + {{paramName}}Param, err := parseNumericParameter[int32]( + query.Get("{{baseName}}"),{{#defaultValue}} + WithDefaultOrParse[int32]({{defaultValue}}, parseInt32),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[int32](parseInt32),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[int32](parseInt32),{{/required}}{{/defaultValue}}{{#minimum}} + WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isInteger}} + {{#isBoolean}} + {{paramName}}Param, err := parseBoolParameter( + query.Get("{{baseName}}"),{{#defaultValue}} + WithDefaultOrParse[bool]({{defaultValue}}, parseBool),{{/defaultValue}}{{^defaultValue}}{{#required}} + WithRequire[bool](parseBool),{{/required}}{{/defaultValue}}{{^defaultValue}}{{^required}} + WithParse[bool](parseBool),{{/required}}{{/defaultValue}} + ) + if err != nil { + w.WriteHeader(500) + return + } + {{/isBoolean}} + {{#isArray}} + {{#items.isNumber}} + {{paramName}}Param, err := parseNumericArrayParameter[float32]( + query.Get("{{baseName}}"), ",", {{required}}, + WithParse[float32](parseFloat32),{{#minimum}} + WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/items.isNumber}} + {{#items.isFloat}} + {{paramName}}Param, err := parseNumericArrayParameter[float32]( + query.Get("{{baseName}}"), ",", {{required}}, + WithParse[float32](parseFloat32),{{#minimum}} + WithMinimum[float32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/items.isFloat}} + {{#items.isDouble}} + {{paramName}}Param, err := parseNumericArrayParameter[float64]( + query.Get("{{baseName}}"), ",", {{required}}, + WithParse[float64](parseFloat64),{{#minimum}} + WithMinimum[float64]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[float64]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/items.isDouble}} + {{#items.isLong}} + {{paramName}}Param, err := parseNumericArrayParameter[int64]( + query.Get("{{baseName}}"), ",", {{required}}, + WithParse[int64](parseInt64),{{#minimum}} + WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int64]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/items.isLong}} + {{#items.isInteger}} + {{paramName}}Param, err := parseNumericArrayParameter[int32]( + query.Get("{{baseName}}"), ",", {{required}}, + WithParse[int32](parseInt32),{{#minimum}} + WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/items.isInteger}} + {{^items.isNumber}} + {{^items.isFloat}} + {{^items.isDouble}} + {{^items.isLong}} + {{^items.isInteger}} + {{paramName}}Param := strings.Split(query.Get("{{baseName}}"), ",") + {{/items.isInteger}} + {{/items.isLong}} + {{/items.isDouble}} + {{/items.isFloat}} + {{/items.isNumber}} + {{/isArray}} + {{^isNumber}} + {{^isFloat}} + {{^isDouble}} + {{^isLong}} + {{^isInteger}} + {{^isBoolean}} + {{^isArray}} + {{#defaultValue}} + {{paramName}}Param := "{{defaultValue}}" + if query.Has("{{baseName}}") { + {{paramName}}Param = query.Get("{{baseName}}") + } + {{/defaultValue}} + {{^defaultValue}} + {{paramName}}Param := query.Get("{{baseName}}") + {{/defaultValue}} + {{/isArray}} + {{/isBoolean}} + {{/isInteger}} + {{/isLong}} + {{/isDouble}} + {{/isFloat}} + {{/isNumber}} + {{/isQueryParam}} + {{#isFormParam}} + {{#isFile}}{{#isArray}} + {{paramName}}Param, err := ReadFormFilesToTempFiles(r, "{{baseName}}"){{/isArray}}{{^isArray}} + {{paramName}}Param, err := ReadFormFileToTempFile(r, "{{baseName}}") + {{/isArray}} + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isFile}} + {{#isLong}}{{#isArray}} + {{paramName}}Param, err := parseNumericArrayParameter[int64]( + r.FormValue("{{baseName}}"), ",", {{required}}, + WithParse[int64](parseInt64),{{#minimum}} + WithMinimum[int64]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int64]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isArray}}{{/isLong}} + {{#isInteger}}{{#isArray}} + {{paramName}}Param, err := parseNumericArrayParameter[int32]( + r.FormValue("{{baseName}}"), ",", {{required}}, + WithParse[int32](parseInt32),{{#minimum}} + WithMinimum[int32]({{minimum}}),{{/minimum}}{{#maximum}} + WithMaximum[int32]({{maximum}}),{{/maximum}} + ) + if err != nil { + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{/isArray}}{{/isInteger}} + {{^isFile}} + {{^isLong}} + {{paramName}}Param := r.FormValue("{{baseName}}") + {{/isLong}} + {{/isFile}} + {{/isFormParam}} + {{#isHeaderParam}} + {{paramName}}Param := r.Header.Get("{{baseName}}") + {{/isHeaderParam}} + {{#isBodyParam}} + {{paramName}}Param := model.{{dataType}}{} + d := json.NewDecoder(r.Body) + {{^isAdditionalPropertiesTrue}} + d.DisallowUnknownFields() + {{/isAdditionalPropertiesTrue}} + if err := d.Decode(&{{paramName}}Param); err != nil {{^required}}&& !errors.Is(err, io.EOF) {{/required}}{ + c.errorHandler(w, r, &ParsingError{Err: err}, nil) + return + } + {{#isArray}} + {{#items.isModel}} + for _, el := range {{paramName}}Param { + if err := Assert{{baseType}}Required(el); err != nil { + c.errorHandler(w, r, err, nil) + return + } + } + {{/items.isModel}} + {{/isArray}} + {{^isArray}} + {{#isModel}} + if err := Assert{{baseType}}Required({{paramName}}Param); err != nil { + c.errorHandler(w, r, err, nil) + return + } + if err := Assert{{baseType}}Constraints({{paramName}}Param); err != nil { + c.errorHandler(w, r, err, nil) + return + } + {{/isModel}} + {{/isArray}} + {{/isBodyParam}} + {{/allParams}} + result, err := c.service.{{nickname}}(r.Context(){{#allParams}}, {{paramName}}Param{{/allParams}}) + // If an error occurred, encode the error with the status code + if err != nil { + c.errorHandler(w, r, err, &result) + return + } + // If no error, encode the body and the result code + EncodeJSONResponse(result.Body, &result.Code,{{#addResponseHeaders}} result.Headers,{{/addResponseHeaders}} w) +}{{/operation}}{{/operations}} From 22bea2de6a3829f150795fdd2703da14efc1b278 Mon Sep 17 00:00:00 2001 From: Tony Davidson Date: Thu, 15 Feb 2024 11:54:20 +0000 Subject: [PATCH 248/254] This commit will remove tonyxrmdavidson and nehachopra27 from OWNERS file. This is needed to allow the do-not-merge/invalid-owners-file label to be removed from https://github.com/openshift/release/pull/48704 (#312) --- OWNERS | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OWNERS b/OWNERS index 2ff7cbf4..534edae6 100644 --- a/OWNERS +++ b/OWNERS @@ -8,18 +8,14 @@ approvers: - dhirajsb - isinyaaa - lampajr -- nehachopra27 - rareddy - rkubis - tarilabs -- tonyxrmdavidson options: {} reviewers: - dhirajsb - isinyaaa - lampajr -- nehachopra27 - rareddy - rkubis - tarilabs -- tonyxrmdavidson From 4060a213cb046430f1b44d755921db27b40627d2 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Thu, 15 Feb 2024 14:22:39 +0100 Subject: [PATCH 249/254] Add parentResourceID param for FindInferenceService (#311) --- api/openapi/model-registry.yaml | 1 + internal/server/openapi/api.go | 2 +- .../openapi/api_model_registry_service.go | 3 ++- .../api_model_registry_service_service.go | 4 ++-- pkg/openapi/api_model_registry_service.go | 18 ++++++++++++++---- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/api/openapi/model-registry.yaml b/api/openapi/model-registry.yaml index c702eee7..7fd4d065 100644 --- a/api/openapi/model-registry.yaml +++ b/api/openapi/model-registry.yaml @@ -482,6 +482,7 @@ paths: parameters: - $ref: "#/components/parameters/name" - $ref: "#/components/parameters/externalID" + - $ref: "#/components/parameters/parentResourceID" "/api/model_registry/v1alpha1/inference_services/{inferenceserviceId}": summary: Path used to manage a single InferenceService. description: >- diff --git a/internal/server/openapi/api.go b/internal/server/openapi/api.go index d4a7584e..e8212f8f 100644 --- a/internal/server/openapi/api.go +++ b/internal/server/openapi/api.go @@ -71,7 +71,7 @@ type ModelRegistryServiceAPIServicer interface { CreateRegisteredModel(context.Context, model.RegisteredModelCreate) (ImplResponse, error) CreateRegisteredModelVersion(context.Context, string, model.ModelVersion) (ImplResponse, error) CreateServingEnvironment(context.Context, model.ServingEnvironmentCreate) (ImplResponse, error) - FindInferenceService(context.Context, string, string) (ImplResponse, error) + FindInferenceService(context.Context, string, string, string) (ImplResponse, error) FindModelArtifact(context.Context, string, string, string) (ImplResponse, error) FindModelVersion(context.Context, string, string, string) (ImplResponse, error) FindRegisteredModel(context.Context, string, string) (ImplResponse, error) diff --git a/internal/server/openapi/api_model_registry_service.go b/internal/server/openapi/api_model_registry_service.go index 62990ee9..6fb7ebee 100644 --- a/internal/server/openapi/api_model_registry_service.go +++ b/internal/server/openapi/api_model_registry_service.go @@ -482,7 +482,8 @@ func (c *ModelRegistryServiceAPIController) FindInferenceService(w http.Response query := r.URL.Query() nameParam := query.Get("name") externalIDParam := query.Get("externalID") - result, err := c.service.FindInferenceService(r.Context(), nameParam, externalIDParam) + parentResourceIDParam := query.Get("parentResourceID") + result, err := c.service.FindInferenceService(r.Context(), nameParam, externalIDParam, parentResourceIDParam) // If an error occurred, encode the error with the status code if err != nil { c.errorHandler(w, r, err, &result) diff --git a/internal/server/openapi/api_model_registry_service_service.go b/internal/server/openapi/api_model_registry_service_service.go index e1134a4c..51713d5d 100644 --- a/internal/server/openapi/api_model_registry_service_service.go +++ b/internal/server/openapi/api_model_registry_service_service.go @@ -165,8 +165,8 @@ func (s *ModelRegistryServiceAPIService) CreateServingEnvironment(ctx context.Co } // FindInferenceService - Get an InferenceServices that matches search parameters. -func (s *ModelRegistryServiceAPIService) FindInferenceService(ctx context.Context, name string, externalID string) (ImplResponse, error) { - result, err := s.coreApi.GetInferenceServiceByParams(&name, nil, &externalID) +func (s *ModelRegistryServiceAPIService) FindInferenceService(ctx context.Context, name string, externalID string, parentResourceID string) (ImplResponse, error) { + result, err := s.coreApi.GetInferenceServiceByParams(&name, &parentResourceID, &externalID) if err != nil { return Response(500, model.Error{Message: err.Error()}), nil } diff --git a/pkg/openapi/api_model_registry_service.go b/pkg/openapi/api_model_registry_service.go index 087ce1e6..b94a7d1f 100644 --- a/pkg/openapi/api_model_registry_service.go +++ b/pkg/openapi/api_model_registry_service.go @@ -1379,10 +1379,11 @@ func (a *ModelRegistryServiceAPIService) CreateServingEnvironmentExecute(r ApiCr } type ApiFindInferenceServiceRequest struct { - ctx context.Context - ApiService *ModelRegistryServiceAPIService - name *string - externalID *string + ctx context.Context + ApiService *ModelRegistryServiceAPIService + name *string + externalID *string + parentResourceID *string } // Name of entity to search. @@ -1397,6 +1398,12 @@ func (r ApiFindInferenceServiceRequest) ExternalID(externalID string) ApiFindInf return r } +// ID of the parent resource to use for search. +func (r ApiFindInferenceServiceRequest) ParentResourceID(parentResourceID string) ApiFindInferenceServiceRequest { + r.parentResourceID = &parentResourceID + return r +} + func (r ApiFindInferenceServiceRequest) Execute() (*InferenceService, *http.Response, error) { return r.ApiService.FindInferenceServiceExecute(r) } @@ -1444,6 +1451,9 @@ func (a *ModelRegistryServiceAPIService) FindInferenceServiceExecute(r ApiFindIn if r.externalID != nil { parameterAddToHeaderOrQuery(localVarQueryParams, "externalID", r.externalID, "") } + if r.parentResourceID != nil { + parameterAddToHeaderOrQuery(localVarQueryParams, "parentResourceID", r.parentResourceID, "") + } // to determine the Content-Type header localVarHTTPContentTypes := []string{} From 3ead8fc54104c2a4376e22b503c5ef77fdc17755 Mon Sep 17 00:00:00 2001 From: Matteo Mortari Date: Fri, 16 Feb 2024 08:41:49 +0100 Subject: [PATCH 250/254] doc: Document MR Logical Model (#301) * doc: Document MR Logical Model * code review: add link from main README.md --- README.md | 4 + docs/logical_model.md | 470 ++++++++++++++++++++++++++++++++++ docs/logical_model_image1.png | Bin 0 -> 40067 bytes docs/logical_model_image2.png | Bin 0 -> 31338 bytes docs/logical_model_image3.png | Bin 0 -> 17732 bytes 5 files changed, 474 insertions(+) create mode 100644 docs/logical_model.md create mode 100644 docs/logical_model_image1.png create mode 100644 docs/logical_model_image2.png create mode 100644 docs/logical_model_image3.png diff --git a/README.md b/README.md index 734b82a5..ecef9dfc 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,10 @@ The proxy service implements the OpenAPI defined in [model-registry.yaml](api/op > **NOTE** The ml-metadata server must be running and accessible from the environment where model-registry starts up. +### Model registry logical model + +For a high-level documentation of the Model Registry _logical model_, please check [this guide](./docs/logical_model.md). + ## Model Registry Core The model registry core is the layer which implements the core/business logic by interacting with the underlying ml-metadata server. diff --git a/docs/logical_model.md b/docs/logical_model.md new file mode 100644 index 00000000..5e6afbe2 --- /dev/null +++ b/docs/logical_model.md @@ -0,0 +1,470 @@ +# Model Registry logical model + +This document provides a brief summary of the Model Registry logical model and its entities. + +## Registered Model + +Represent logically a given ML model. + +Examples: + +* a given Git repo +* a given Container image registry repo/name +* a given Hugging Face repo +* “ChatGPT”, “Stable Diffusion”, “Phi”, “Mistral” + +> [!NOTE] +> Implemented as MLMD Context. + +## Model Version + +![Model Version](./logical_model_image3.png "Model Version") + +Represent a specific version of a given Registered Model. + +Examples: + +* A git tag +* A container image tag +* “v1.0” + +> [!NOTE] +> Implemented as a MLMD Context with parent-context to the Registered Model. To avoid name clash this is technically named with the prefix of the owned entity (Registered Model). + + +## Model Artifact + +![Model Artifact](./logical_model_image2.png "Model Artifact") + +Represent the ML model artifact in a given Model Version. + +Examples: + +* An ONNX file +* A Pickle file +* A checkpoint .ckpt file + +Provides several properties which can be used to locate and identify the model artifact/file (on storage). Some of the properties, such as **storage_key** and **storage_path**, are loosely modeled after KServe InferenceService’s [storage spec](https://github.com/kserve/kserve/blob/d977cc0c89d32a029123635f216c82d287683775/pkg/apis/serving/v1beta1/predictor.go#L89) for historical reasons (and [integration](https://github.com/kserve/modelmesh-serving/blob/release-0.11/docs/quickstart.md#2-deploy-a-model) [blueprints](https://github.com/kserve/kserve/blob/master/docs/samples/storage/storageSpec/README.md#create-the-inferenceservice)), but we found it providing a flexible, general logical structure to capture “a storage pointer and resolver” which can be applied to several technical solutions beyond KServe or Model Mesh. + +`uri` can be used as a general mechanism to locate the model artifact/file on storage. We recommend using the URI protocol to identify the kind of storage, while the remainder to locate the artifact/file. This makes it possible for downstream use to leverage URI as the resolution mechanism, eventually augmented with credentials to be supplied by platform idiomatic choice for secret management and access control. + +`storage_key` can be used to reference the access key to be used in conjunction with URI (above) in order to gain access to the artifact/file. + +For example, this can be the name of a Kubernetes Secret or a given entry in a Vault. + +`storage_path` might be used to further qualify the location of the model artifact/file within the URI. + +Further attributes which might be needed or helpful to provide access to the Model artifact/file at the URI, shall be placed in the `customProperties`. + +The combination of `uri`, `storage_key`, `storage_path` and additional `customProperties` might be used downstream to determine access strategy to the model artifact/file at the uri, for example: + +* use CustomStorageInitializer: [https://kserve.github.io/website/master/modelserving/storage/storagecontainers/](https://kserve.github.io/website/master/modelserving/storage/storagecontainers/) +* use the python function from the point above in a non-Kubernetes context +* reimplement the python function from the point above in a non-Kubernetes context and in the preferred language of choice + +> [!NOTE] +> Implemented as a MLMD Artifact with MLMD Association to the Model Version. To avoid name clashes this is technically named with the prefix of the owned entity (Model Version). + + +### Examples of Model Artifact details + +Please notice the method `register_model()` is a fluent way to do at-once _upsertion_ of RegisteredModel, ModelVersion along with the ModelArtifact. + +A ML model from GitHub: + +```python +model = registry.register_model( + "my-model-from-gh", + "https://github.com/tarilabs/demo20231212/raw/main/v1.nb20231206162408/mnist.onnx", + version="v1", + description="used for demo purposes", + model_format_name="onnx", + model_format_version="1" +) +``` + +resulting in: + +``` +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/1" \ + -H 'accept: application/json' | jq +{ + "createTimeSinceEpoch": "1707765353963", + "customProperties": {}, + "id": "1", + "lastUpdateTimeSinceEpoch": "1707765353963", + "name": "my-model-from-gh", + "state": "LIVE" +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/1/versions?pageSize=100&orderBy=ID&sortOrder=DESC&nextPageToken=" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "author": "mmortari", + "createTimeSinceEpoch": "1707765354455", + "customProperties": {}, + "description": "used for demo purposes", + "id": "2", + "lastUpdateTimeSinceEpoch": "1707765354455", + "name": "v1", + "state": "LIVE" + } + ], + "nextPageToken": "", + "pageSize": 100, + "size": 1 +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/model_versions/2/artifacts" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "artifactType": "model-artifact", + "createTimeSinceEpoch": "1707765355147", + "customProperties": {}, + "id": "1", + "lastUpdateTimeSinceEpoch": "1707765355147", + "modelFormatName": "onnx", + "modelFormatVersion": "1", + "name": "my-model-from-gh", + "state": "UNKNOWN", + "uri": "https://github.com/tarilabs/demo20231212/raw/main/v1.nb20231206162408/mnist.onnx" + } + ], + "nextPageToken": "", + "pageSize": 0, + "size": 1 +} +``` + +A ML model from S3 bucket referencing a K8s Secret: + +```python +model = registry.register_model( + "my-model-from-s3", + "s3://mybucket/v1.nb20231222141832/mnist.onnx", + version="v1.nb20231222141832", + description="used for demo purposes", + model_format_name="onnx", + model_format_version="1", + storage_key="aws-connection-mybucket", + storage_path="v1.nb20231222141832" +) +``` + +please notice: + +* `storage_key` can be used to reference a Kubernetes Secret, containing AWS_S3_ENDPOINT, AWS_S3_BUCKET, etc. +* `storage_path` can be used in place of determining the bucket and path from s3:// -like uri, and rely on the storage_key secret’s AWS_S3_BUCKET + +resulting in: + +``` +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/3" \ + -H 'accept: application/json' | jq +{ + "createTimeSinceEpoch": "1707765756856", + "customProperties": {}, + "id": "3", + "lastUpdateTimeSinceEpoch": "1707765756856", + "name": "my-model-from-s3", + "state": "LIVE" +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/3/versions?pageSize=100&orderBy=ID&sortOrder=DESC&nextPageToken=" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "author": "mmortari", + "createTimeSinceEpoch": "1707765757254", + "customProperties": {}, + "description": "used for demo purposes", + "id": "4", + "lastUpdateTimeSinceEpoch": "1707765757254", + "name": "v1.nb20231222141832", + "state": "LIVE" + } + ], + "nextPageToken": "", + "pageSize": 100, + "size": 1 +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/model_versions/4/artifacts" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "artifactType": "model-artifact", + "createTimeSinceEpoch": "1707765757755", + "customProperties": {}, + "id": "2", + "lastUpdateTimeSinceEpoch": "1707765757755", + "modelFormatName": "onnx", + "modelFormatVersion": "1", + "name": "my-model-from-s3", + "state": "UNKNOWN", + "storageKey": "aws-connection-mybucket", + "storagePath": "v1.nb20231222141832", + "uri": "s3://mybucket/v1.nb20231222141832/mnist.onnx" + } + ], + "nextPageToken": "", + "pageSize": 0, + "size": 1 +} +``` + +A ML model from S3 bucket with all required location details except of credentials: + +```python +model = registry.register_model( + "my-model-from-s3-anotherone", + "s3://mybucket/v1.nb20231222141832/mnist.onnx", + version="v1.nb20231222141832", + description="used for demo purposes", + model_format_name="onnx", + model_format_version="1", + storage_key="aws-connection-mybucket", + storage_path="v1.nb20231222141832", + metadata={ + key: os.environ[key] for key in ['AWS_S3_ENDPOINT', 'AWS_S3_BUCKET', 'AWS_DEFAULT_REGION'] if key in os.environ + } +) +``` + +resulting in: + +``` +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/5" \ + -H 'accept: application/json' | jq +{ + "createTimeSinceEpoch": "1707765990857", + "customProperties": {}, + "id": "5", + "lastUpdateTimeSinceEpoch": "1707765990857", + "name": "my-model-from-s3-anotherone", + "state": "LIVE" +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/5/versions?pageSize=100&orderBy=ID&sortOrder=DESC&nextPageToken=" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "author": "mmortari", + "createTimeSinceEpoch": "1707765991255", + "customProperties": { + "AWS_DEFAULT_REGION": { + "string_value": "us-east-1" + }, + "AWS_S3_BUCKET": { + "string_value": "mybucket" + }, + "AWS_S3_ENDPOINT": { + "string_value": "https://minio-..." + } + }, + "description": "used for demo purposes", + "id": "6", + "lastUpdateTimeSinceEpoch": "1707765991255", + "name": "v1.nb20231222141832", + "state": "LIVE" + } + ], + "nextPageToken": "", + "pageSize": 100, + "size": 1 +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/model_versions/6/artifacts" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "artifactType": "model-artifact", + "createTimeSinceEpoch": "1707765991755", + "customProperties": {}, + "id": "3", + "lastUpdateTimeSinceEpoch": "1707765991755", + "modelFormatName": "onnx", + "modelFormatVersion": "1", + "name": "my-model-from-s3-anotherone", + "state": "UNKNOWN", + "storageKey": "aws-connection-mybucket", + "storagePath": "v1.nb20231222141832", + "uri": "s3://mybucket/v1.nb20231222141832/mnist.onnx" + } + ], + "nextPageToken": "", + "pageSize": 0, + "size": 1 +} +``` + +or with supplied-values: + +```python +model = registry.register_model( + "my-model-from-s3-anotherone", + "s3://mybucket/v1.nb20231222141832/mnist.onnx", + version="v1.nb20231222141832", + description="used for demo purposes", + model_format_name="onnx", + model_format_version="1", + storage_key="aws-connection-mybucket", + storage_path="v1.nb20231222141832", + metadata={ + "AWS_S3_ENDPOINT": "https://minio-...", + "AWS_S3_BUCKET": "mybucket", + "AWS_DEFAULT_REGION": "us-east-1", + } +) +``` + +please note this example contains all the required details in order to reproduce access to the S3 bucket, with the exception of AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY credentials which were omitted while indexing on Model Registry intentionally. + +These additional details can also be used by the downstream solution, for example, to: + +1. first, create a K8s Secret “aws-connection-mybucket” with the Endpoint, Bucket, Region and externally user-supplied credentials, +2. then, fallback into the previous example use-case + +A ML model from S3 bucket using a ServiceAccount: + +```python +model = registry.register_model( + "mnist-s3", + "s3://kserve-examples/mnist", + version="v1", + description="used for demo purposes", + model_format_name="onnx", + model_format_version="1", + service_account_name="sa", +) +``` + +this example make reference to KServe tutorial: [https://kserve.github.io/website/master/modelserving/storage/s3/s3/#deploy-the-model-on-s3-with-inferenceservice](https://kserve.github.io/website/master/modelserving/storage/s3/s3/#deploy-the-model-on-s3-with-inferenceservice) + +resulting in: + +``` +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/7" \ + -H 'accept: application/json' | jq +{ + "createTimeSinceEpoch": "1707766117250", + "customProperties": {}, + "id": "7", + "lastUpdateTimeSinceEpoch": "1707766117250", + "name": "mnist-s3", + "state": "LIVE" +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/registered_models/7/versions?pageSize=100&orderBy=ID&sortOrder=DESC&nextPageToken=" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "author": "mmortari", + "createTimeSinceEpoch": "1707766117651", + "customProperties": {}, + "description": "used for demo purposes", + "id": "8", + "lastUpdateTimeSinceEpoch": "1707766117651", + "name": "v1", + "state": "LIVE" + } + ], + "nextPageToken": "", + "pageSize": 100, + "size": 1 +} + +curl --silent -X 'GET' \ + "$MR_HOSTNAME/api/model_registry/v1alpha1/model_versions/8/artifacts" \ + -H 'accept: application/json' | jq +{ + "items": [ + { + "artifactType": "model-artifact", + "createTimeSinceEpoch": "1707766118244", + "customProperties": {}, + "id": "4", + "lastUpdateTimeSinceEpoch": "1707766118244", + "modelFormatName": "onnx", + "modelFormatVersion": "1", + "name": "mnist-s3", + "serviceAccountName": "sa", + "state": "UNKNOWN", + "uri": "s3://kserve-examples/mnist" + } + ], + "nextPageToken": "", + "pageSize": 0, + "size": 1 +} +``` + +## Doc Artifact + +![Doc Artifact](./logical_model_image1.png "Doc Artifact") + + +Represent additional documentation artifacts in a given Model Version. + +Examples: + +* A README.md file + +> [!NOTE] +> Implemented as a MLMD Artifact with MLMD Association to the Model Version. To avoid name clashes this is technically named with the prefix of the owned entity (Model Version). + + +## Logical model diagram + +This diagram summarizes the relationship between the entities: + +```mermaid +classDiagram + class RegisteredModel{ + +String name + +Map customProperties + } + class ModelVersion{ + +String name + +Map customProperties + } + class Artifact{ + Enum artifactType + +String name + +String uri + +Map customProperties + } + class ModelArtifact{ + +String modelFormatName + +String modelFormatVersion + +String storageKey + +String storagePath + +String serviceAccountName + } + RegisteredModel "1" <--> "*" ModelVersion + ModelVersion "0..1" -- "*" Artifact + ModelArtifact --|> Artifact + DocArtifact --|> Artifact +``` + +note: in order to keep the diagram simple, only the most relevant properties of each entity are depicted. diff --git a/docs/logical_model_image1.png b/docs/logical_model_image1.png new file mode 100644 index 0000000000000000000000000000000000000000..f3ae0e99c18d034db93f850cc2dd99636c9b759c GIT binary patch literal 40067 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 JR$s9U`EQsJaiahL literal 0 HcmV?d00001 diff --git a/docs/logical_model_image2.png b/docs/logical_model_image2.png new file mode 100644 index 0000000000000000000000000000000000000000..4cadedfcc79527ff3937e0d10a8f2cbebf039d5f GIT binary patch literal 31338 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 literal 0 HcmV?d00001 diff --git a/docs/logical_model_image3.png b/docs/logical_model_image3.png new file mode 100644 index 0000000000000000000000000000000000000000..5d338124349077e7cfdd4f0283bd3905a1183315 GIT binary patch literal 17732 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 Date: Fri, 16 Feb 2024 08:58:46 +0100 Subject: [PATCH 251/254] py: default metadata capture environment vars (#307) * py: default metadata capture environment vars * linting --- clients/python/README.md | 5 ++ clients/python/src/model_registry/_client.py | 19 +++++- clients/python/tests/test_client.py | 67 +++++++++++++++++++- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/clients/python/README.md b/clients/python/README.md index f088f844..febca492 100644 --- a/clients/python/README.md +++ b/clients/python/README.md @@ -37,6 +37,11 @@ version = registry.get_model_version("my-model", "v2.0") experiment = registry.get_model_artifact("my-model", "v2.0") ``` +### Default values for metadata + +If not supplied, `metadata` values defaults to a predefined set of conventional values. +Reference the technical documentation in the pydoc of the client. + ### Importing from Hugging Face Hub To import models from Hugging Face Hub, start by installing the `huggingface-hub` package, either directly or as an diff --git a/clients/python/src/model_registry/_client.py b/clients/python/src/model_registry/_client.py index a4d5bafc..826f061f 100644 --- a/clients/python/src/model_registry/_client.py +++ b/clients/python/src/model_registry/_client.py @@ -1,6 +1,7 @@ """Standard client for the model registry.""" from __future__ import annotations +import os from typing import get_args from warnings import warn @@ -98,7 +99,7 @@ def register_model( storage_key: Storage key. storage_path: Storage path. service_account_name: Service account name. - metadata: Additional version metadata. + metadata: Additional version metadata. Defaults to values returned by `default_metadata()`. Returns: Registered model. @@ -109,7 +110,7 @@ def register_model( version, author or self._author, description=description, - metadata=metadata or {}, + metadata=metadata or self.default_metadata(), ) self._register_model_artifact( mv, @@ -123,6 +124,19 @@ def register_model( return rm + def default_metadata(self) -> dict[str, ScalarType]: + """Default metadata valorisations. + + When not explicitly supplied by the end users, these valorisations will be used + by default. + + Returns: + default metadata valorisations. + """ + return { + key: os.environ[key] for key in ["AWS_S3_ENDPOINT", "AWS_S3_BUCKET", "AWS_DEFAULT_REGION"] if key in os.environ + } + def register_hf_model( self, repo: str, @@ -188,6 +202,7 @@ def register_hf_model( model_author = author source_uri = hf_hub_url(repo, path, revision=git_ref) metadata = { + **self.default_metadata(), "repo": repo, "source_uri": source_uri, "model_origin": "huggingface_hub", diff --git a/clients/python/tests/test_client.py b/clients/python/tests/test_client.py index 7dee53ca..9e33b07b 100644 --- a/clients/python/tests/test_client.py +++ b/clients/python/tests/test_client.py @@ -1,3 +1,5 @@ +import os + import pytest from model_registry import ModelRegistry from model_registry.core import ModelRegistryAPIClient @@ -46,6 +48,7 @@ def test_register_existing_version(mr_client: ModelRegistry): def test_get(mr_client: ModelRegistry): name = "test_model" version = "1.0.0" + metadata = {"a": 1, "b": "2"} rm = mr_client.register_model( name, @@ -53,6 +56,7 @@ def test_get(mr_client: ModelRegistry): model_format_name="test_format", model_format_version="test_version", version=version, + metadata=metadata ) assert (_rm := mr_client.get_registered_model(name)) @@ -64,22 +68,81 @@ def test_get(mr_client: ModelRegistry): assert (_mv := mr_client.get_model_version(name, version)) assert mv.id == _mv.id + assert mv.metadata == metadata assert (_ma := mr_client.get_model_artifact(name, version)) assert ma.id == _ma.id +def test_default_md(mr_client: ModelRegistry): + name = "test_model" + version = "1.0.0" + env_values = {"AWS_S3_ENDPOINT": "value1", "AWS_S3_BUCKET": "value2", "AWS_DEFAULT_REGION": "value3"} + for k, v in env_values.items(): + os.environ[k] = v + + assert mr_client.register_model( + name, + "s3", + model_format_name="test_format", + model_format_version="test_version", + version=version, + # ensure leave empty metadata + ) + assert (mv := mr_client.get_model_version(name, version)) + assert mv.metadata == env_values + + for k in env_values: + os.environ.pop(k) + + def test_hf_import(mr_client: ModelRegistry): pytest.importorskip("huggingface_hub") name = "openai-community/gpt2" version = "1.2.3" + author = "test author" + + assert mr_client.register_hf_model( + name, + "onnx/decoder_model.onnx", + author=author, + version=version, + model_format_name="test format", + model_format_version="test version", + ) + assert (mv := mr_client.get_model_version(name, version)) + assert mv.author == author + assert mv.metadata["model_author"] == author + assert mv.metadata["model_origin"] == "huggingface_hub" + assert mv.metadata["source_uri"] == "https://huggingface.co/openai-community/gpt2/resolve/main/onnx/decoder_model.onnx" + assert mv.metadata["repo"] == name + assert mr_client.get_model_artifact(name, version) + + +def test_hf_import_default_env(mr_client: ModelRegistry): + """Test setting environment variables, hence triggering defaults, does _not_ interfere with HF metadata + """ + pytest.importorskip("huggingface_hub") + name = "openai-community/gpt2" + version = "1.2.3" + author = "test author" + env_values = {"AWS_S3_ENDPOINT": "value1", "AWS_S3_BUCKET": "value2", "AWS_DEFAULT_REGION": "value3"} + for k, v in env_values.items(): + os.environ[k] = v assert mr_client.register_hf_model( name, "onnx/decoder_model.onnx", - author="test author", + author=author, version=version, model_format_name="test format", model_format_version="test version", ) - assert mr_client.get_model_version(name, version) + assert (mv := mr_client.get_model_version(name, version)) + assert mv.metadata["model_author"] == author + assert mv.metadata["model_origin"] == "huggingface_hub" + assert mv.metadata["source_uri"] == "https://huggingface.co/openai-community/gpt2/resolve/main/onnx/decoder_model.onnx" + assert mv.metadata["repo"] == name assert mr_client.get_model_artifact(name, version) + + for k in env_values: + os.environ.pop(k) From 78b0971a1d46966d1614935a1236237da095f6a8 Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Sat, 17 Feb 2024 04:07:00 -0600 Subject: [PATCH 252/254] Improvements to Makefile (#314) Signed-off-by: Andrew Block --- Makefile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index e99a021d..9147383f 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ internal/ml_metadata/proto/%.pb.go: api/grpc/ml_metadata/proto/%.proto gen/grpc: internal/ml_metadata/proto/metadata_store.pb.go internal/ml_metadata/proto/metadata_store_service.pb.go internal/converter/generated/converter.go: internal/converter/*.go - goverter gen github.com/opendatahub-io/model-registry/internal/converter/ + ${GOVERTER} gen github.com/opendatahub-io/model-registry/internal/converter/ .PHONY: gen/converter gen/converter: gen/grpc internal/converter/generated/converter.go @@ -67,7 +67,7 @@ gen/converter: gen/grpc internal/converter/generated/converter.go # validate the openapi schema .PHONY: openapi/validate openapi/validate: bin/openapi-generator-cli - @openapi-generator-cli validate -i api/openapi/model-registry.yaml + ${OPENAPI_GENERATOR} validate -i api/openapi/model-registry.yaml # generate the openapi server implementation .PHONY: gen/openapi-server @@ -86,7 +86,7 @@ gen/openapi: bin/openapi-generator-cli openapi/validate pkg/openapi/client.go pkg/openapi/client.go: bin/openapi-generator-cli api/openapi/model-registry.yaml rm -rf pkg/openapi - openapi-generator-cli generate \ + ${OPENAPI_GENERATOR} generate \ -i api/openapi/model-registry.yaml -g go -o pkg/openapi --package-name openapi \ --ignore-file-override ./.openapi-generator-ignore --additional-properties=isGoSubmodule=true,enumClassPrefix=true,useOneOfDiscriminatorLookup=true gofmt -w pkg/openapi @@ -112,9 +112,11 @@ bin/protoc-gen-go: bin/protoc-gen-go-grpc: GOBIN=$(PROJECT_BIN) go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0 +GOLANGCI_LINT ?= ${PROJECT_BIN}/golangci-lint bin/golangci-lint: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(PROJECT_BIN) v1.54.2 +GOVERTER ?= ${PROJECT_BIN}/goverter bin/goverter: GOBIN=$(PROJECT_PATH)/bin go install github.com/jmattheis/goverter/cmd/goverter@v1.1.1 @@ -161,8 +163,8 @@ gen: deps gen/grpc gen/openapi gen/openapi-server gen/converter .PHONY: lint lint: - golangci-lint run main.go - golangci-lint run cmd/... internal/... ./pkg/... + ${GOLANGCI_LINT} run main.go + ${GOLANGCI_LINT} run cmd/... internal/... ./pkg/... .PHONY: test test: gen From ec8618e4ec081028b71e431f429191ff888a07f5 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Sat, 17 Feb 2024 02:12:15 -0800 Subject: [PATCH 253/254] feat: add kustomize manifests for kubeflow, fixes RHOAIENG-1947 (#292) --- manifests/kustomize/base/kustomization.yaml | 10 ++ .../base/model-registry-configmap.yaml | 11 ++ .../base/model-registry-deployment.yaml | 103 ++++++++++++++++++ .../kustomize/base/model-registry-sa.yaml | 4 + .../base/model-registry-service.yaml | 17 +++ .../options/istio/destination-rule.yaml | 9 ++ .../istio/istio-authorization-policy.yaml | 11 ++ .../options/istio/kustomization.yaml | 7 ++ .../options/istio/virtual-service.yaml | 21 ++++ .../kustomize/overlays/db/kustomization.yaml | 38 +++++++ .../db/model-registry-db-deployment.yaml | 52 +++++++++ .../overlays/db/model-registry-db-pvc.yaml | 10 ++ .../db/model-registry-db-service.yaml | 14 +++ manifests/kustomize/overlays/db/params.env | 3 + .../db/patches/model-registry-deployment.yaml | 37 +++++++ manifests/kustomize/overlays/db/secrets.env | 2 + .../overlays/postgres/kustomization.yaml | 38 +++++++ .../model-registry-db-deployment.yaml | 43 ++++++++ .../postgres/model-registry-db-pvc.yaml | 10 ++ .../postgres/model-registry-db-service.yaml | 14 +++ .../kustomize/overlays/postgres/params.env | 2 + .../patches/model-registry-deployment.yaml | 28 +++++ .../kustomize/overlays/postgres/secrets.env | 2 + 23 files changed, 486 insertions(+) create mode 100644 manifests/kustomize/base/kustomization.yaml create mode 100644 manifests/kustomize/base/model-registry-configmap.yaml create mode 100644 manifests/kustomize/base/model-registry-deployment.yaml create mode 100644 manifests/kustomize/base/model-registry-sa.yaml create mode 100644 manifests/kustomize/base/model-registry-service.yaml create mode 100644 manifests/kustomize/options/istio/destination-rule.yaml create mode 100644 manifests/kustomize/options/istio/istio-authorization-policy.yaml create mode 100644 manifests/kustomize/options/istio/kustomization.yaml create mode 100644 manifests/kustomize/options/istio/virtual-service.yaml create mode 100644 manifests/kustomize/overlays/db/kustomization.yaml create mode 100644 manifests/kustomize/overlays/db/model-registry-db-deployment.yaml create mode 100644 manifests/kustomize/overlays/db/model-registry-db-pvc.yaml create mode 100644 manifests/kustomize/overlays/db/model-registry-db-service.yaml create mode 100644 manifests/kustomize/overlays/db/params.env create mode 100644 manifests/kustomize/overlays/db/patches/model-registry-deployment.yaml create mode 100644 manifests/kustomize/overlays/db/secrets.env create mode 100644 manifests/kustomize/overlays/postgres/kustomization.yaml create mode 100644 manifests/kustomize/overlays/postgres/model-registry-db-deployment.yaml create mode 100644 manifests/kustomize/overlays/postgres/model-registry-db-pvc.yaml create mode 100644 manifests/kustomize/overlays/postgres/model-registry-db-service.yaml create mode 100644 manifests/kustomize/overlays/postgres/params.env create mode 100644 manifests/kustomize/overlays/postgres/patches/model-registry-deployment.yaml create mode 100644 manifests/kustomize/overlays/postgres/secrets.env diff --git a/manifests/kustomize/base/kustomization.yaml b/manifests/kustomize/base/kustomization.yaml new file mode 100644 index 00000000..5d497c83 --- /dev/null +++ b/manifests/kustomize/base/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - model-registry-configmap.yaml + - model-registry-deployment.yaml + - model-registry-service.yaml + - model-registry-sa.yaml +images: + - name: gcr.io/ml-pipeline/metadata-envoy + newTag: 2.0.5 diff --git a/manifests/kustomize/base/model-registry-configmap.yaml b/manifests/kustomize/base/model-registry-configmap.yaml new file mode 100644 index 00000000..8d884532 --- /dev/null +++ b/manifests/kustomize/base/model-registry-configmap.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: model-registry-configmap + labels: + component: model-registry-server +data: + MODEL_REGISTRY_REST_SERVICE_HOST: "model-registry-service" + MODEL_REGISTRY_REST_SERVICE_PORT: "8080" + MODEL_REGISTRY_GRPC_SERVICE_HOST: "model-registry-service" + MODEL_REGISTRY_GRPC_SERVICE_PORT: "9090" diff --git a/manifests/kustomize/base/model-registry-deployment.yaml b/manifests/kustomize/base/model-registry-deployment.yaml new file mode 100644 index 00000000..7022ee17 --- /dev/null +++ b/manifests/kustomize/base/model-registry-deployment.yaml @@ -0,0 +1,103 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-deployment + labels: + component: model-registry-server +spec: + replicas: 1 + selector: + matchLabels: + component: model-registry-server + template: + metadata: + labels: + component: model-registry-server + spec: + containers: + - name: rest-container + args: + - --hostname=0.0.0.0 + - --port=8080 + - --mlmd-hostname=localhost + - --mlmd-port=9090 + command: + - /model-registry + - proxy + image: quay.io/opendatahub/model-registry:latest + # empty placeholder environment for patching + env: [] + ports: + - name: http-api + containerPort: 8080 + livenessProbe: + initialDelaySeconds: 30 + periodSeconds: 5 + tcpSocket: + port: http-api + timeoutSeconds: 2 + readinessProbe: + initialDelaySeconds: 3 + periodSeconds: 5 + tcpSocket: + port: http-api + timeoutSeconds: 2 + - name: grpc-container + # ! Sync to the same MLMD version: + # * backend/metadata_writer/requirements.in and requirements.txt + # * @kubeflow/frontend/src/mlmd/generated + # * .cloudbuild.yaml and .release.cloudbuild.yaml + # * manifests/kustomize/base/metadata/base/model-registry-deployment.yaml + # * test/tag_for_hosted.sh + image: gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0 + env: + - name: DBCONFIG_USER + valueFrom: + secretKeyRef: + name: mysql-secret + key: username + - name: DBCONFIG_PASSWORD + valueFrom: + secretKeyRef: + name: mysql-secret + key: password + - name: MYSQL_DATABASE + valueFrom: + configMapKeyRef: + name: pipeline-install-config + key: mlmdDb + - name: MYSQL_HOST + valueFrom: + configMapKeyRef: + name: pipeline-install-config + key: dbHost + - name: MYSQL_PORT + valueFrom: + configMapKeyRef: + name: pipeline-install-config + key: dbPort + command: ["/bin/metadata_store_server"] + args: ["--grpc_port=9090", + "--mysql_config_database=$(MYSQL_DATABASE)", + "--mysql_config_host=$(MYSQL_HOST)", + "--mysql_config_port=$(MYSQL_PORT)", + "--mysql_config_user=$(DBCONFIG_USER)", + "--mysql_config_password=$(DBCONFIG_PASSWORD)", + "--enable_database_upgrade=true" + ] + ports: + - name: grpc-api + containerPort: 9090 + livenessProbe: + tcpSocket: + port: grpc-api + initialDelaySeconds: 3 + periodSeconds: 5 + timeoutSeconds: 2 + readinessProbe: + tcpSocket: + port: grpc-api + initialDelaySeconds: 3 + periodSeconds: 5 + timeoutSeconds: 2 + serviceAccountName: model-registry-server diff --git a/manifests/kustomize/base/model-registry-sa.yaml b/manifests/kustomize/base/model-registry-sa.yaml new file mode 100644 index 00000000..8cfc77ef --- /dev/null +++ b/manifests/kustomize/base/model-registry-sa.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: model-registry-server diff --git a/manifests/kustomize/base/model-registry-service.yaml b/manifests/kustomize/base/model-registry-service.yaml new file mode 100644 index 00000000..d7d362c3 --- /dev/null +++ b/manifests/kustomize/base/model-registry-service.yaml @@ -0,0 +1,17 @@ +kind: Service +apiVersion: v1 +metadata: + labels: + app: metadata + name: model-registry-service +spec: + selector: + component: model-registry-server + type: ClusterIP + ports: + - port: 8080 + protocol: TCP + name: http-api + - port: 9090 + protocol: TCP + name: grpc-api diff --git a/manifests/kustomize/options/istio/destination-rule.yaml b/manifests/kustomize/options/istio/destination-rule.yaml new file mode 100644 index 00000000..179d62d2 --- /dev/null +++ b/manifests/kustomize/options/istio/destination-rule.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: model-registry-service +spec: + host: model-registry-service.kubeflow.svc.cluster.local + trafficPolicy: + tls: + mode: ISTIO_MUTUAL diff --git a/manifests/kustomize/options/istio/istio-authorization-policy.yaml b/manifests/kustomize/options/istio/istio-authorization-policy.yaml new file mode 100644 index 00000000..36685d8f --- /dev/null +++ b/manifests/kustomize/options/istio/istio-authorization-policy.yaml @@ -0,0 +1,11 @@ +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: model-registry-service +spec: + action: ALLOW + selector: + matchLabels: + component: model-registry-server + rules: + - {} diff --git a/manifests/kustomize/options/istio/kustomization.yaml b/manifests/kustomize/options/istio/kustomization.yaml new file mode 100644 index 00000000..029a6937 --- /dev/null +++ b/manifests/kustomize/options/istio/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- istio-authorization-policy.yaml +- destination-rule.yaml +- virtual-service.yaml diff --git a/manifests/kustomize/options/istio/virtual-service.yaml b/manifests/kustomize/options/istio/virtual-service.yaml new file mode 100644 index 00000000..1cbdaeb2 --- /dev/null +++ b/manifests/kustomize/options/istio/virtual-service.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: model-registry + namespace: kubeflow +spec: + gateways: + - kubeflow-gateway + hosts: + - '*' + http: + - match: + - uri: + prefix: /ml_metadata + rewrite: + uri: /ml_metadata + route: + - destination: + host: metadata-envoy-service.kubeflow.svc.cluster.local + port: + number: 9090 diff --git a/manifests/kustomize/overlays/db/kustomization.yaml b/manifests/kustomize/overlays/db/kustomization.yaml new file mode 100644 index 00000000..42fea9f0 --- /dev/null +++ b/manifests/kustomize/overlays/db/kustomization.yaml @@ -0,0 +1,38 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow + +resources: +- model-registry-db-pvc.yaml +- model-registry-db-deployment.yaml +- model-registry-db-service.yaml +- ../../base + +patchesStrategicMerge: +- patches/model-registry-deployment.yaml + +configMapGenerator: +- envs: + - params.env + name: model-registry-db-parameters +secretGenerator: +- envs: + - secrets.env + name: model-registry-db-secrets +generatorOptions: + disableNameSuffixHash: true + + +images: +- name: mysql + newName: mysql + newTag: 8.0.3 + +vars: +- fieldref: + fieldPath: metadata.name + name: MLMD_DB_HOST + objref: + apiVersion: v1 + kind: Service + name: model-registry-db diff --git a/manifests/kustomize/overlays/db/model-registry-db-deployment.yaml b/manifests/kustomize/overlays/db/model-registry-db-deployment.yaml new file mode 100644 index 00000000..7f1477aa --- /dev/null +++ b/manifests/kustomize/overlays/db/model-registry-db-deployment.yaml @@ -0,0 +1,52 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-db + labels: + component: db +spec: + selector: + matchLabels: + component: db + replicas: 1 + strategy: + type: Recreate + template: + metadata: + name: db + labels: + component: db + annotations: + sidecar.istio.io/inject: "false" + spec: + containers: + - name: db-container + image: mysql:8.0.3 + args: + - --datadir + - /var/lib/mysql/datadir + - --default-authentication-plugin=mysql_native_password + envFrom: + - configMapRef: + name: model-registry-db-parameters + - secretRef: + name: model-registry-db-secrets + ports: + - name: dbapi + containerPort: 3306 + readinessProbe: + exec: + command: + - "/bin/bash" + - "-c" + - "mysql -D $$MYSQL_DATABASE -u$$MYSQL_USER_NAME -p$$MYSQL_ROOT_PASSWORD -e 'SELECT 1'" + initialDelaySeconds: 5 + periodSeconds: 2 + timeoutSeconds: 1 + volumeMounts: + - name: metadata-mysql + mountPath: /var/lib/mysql + volumes: + - name: metadata-mysql + persistentVolumeClaim: + claimName: metadata-mysql diff --git a/manifests/kustomize/overlays/db/model-registry-db-pvc.yaml b/manifests/kustomize/overlays/db/model-registry-db-pvc.yaml new file mode 100644 index 00000000..b1c083d9 --- /dev/null +++ b/manifests/kustomize/overlays/db/model-registry-db-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: metadata-mysql +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi diff --git a/manifests/kustomize/overlays/db/model-registry-db-service.yaml b/manifests/kustomize/overlays/db/model-registry-db-service.yaml new file mode 100644 index 00000000..f27c8c76 --- /dev/null +++ b/manifests/kustomize/overlays/db/model-registry-db-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: model-registry-db + labels: + component: db +spec: + type: ClusterIP + ports: + - port: 3306 + protocol: TCP + name: dbapi + selector: + component: db diff --git a/manifests/kustomize/overlays/db/params.env b/manifests/kustomize/overlays/db/params.env new file mode 100644 index 00000000..5ab2adb3 --- /dev/null +++ b/manifests/kustomize/overlays/db/params.env @@ -0,0 +1,3 @@ +MYSQL_DATABASE=metadb +MYSQL_PORT=3306 +MYSQL_ALLOW_EMPTY_PASSWORD=true \ No newline at end of file diff --git a/manifests/kustomize/overlays/db/patches/model-registry-deployment.yaml b/manifests/kustomize/overlays/db/patches/model-registry-deployment.yaml new file mode 100644 index 00000000..5d788ed7 --- /dev/null +++ b/manifests/kustomize/overlays/db/patches/model-registry-deployment.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-deployment +spec: + template: + spec: + containers: + - name: rest-container + # Remove existing environment variables + env: + - $patch: replace + envFrom: + - configMapRef: + name: model-registry-configmap + args: + - --hostname=0.0.0.0 + - --port=$(MODEL_REGISTRY_REST_SERVICE_PORT) + - --mlmd-hostname=localhost + - --mlmd-port=$(MODEL_REGISTRY_GRPC_SERVICE_PORT) + - name: grpc-container + # Remove existing environment variables + env: + - $patch: replace + envFrom: + - configMapRef: + name: model-registry-db-parameters + - secretRef: + name: model-registry-db-secrets + - configMapRef: + name: model-registry-configmap + args: ["--grpc_port=$(MODEL_REGISTRY_GRPC_SERVICE_PORT)", + "--mysql_config_host=$(MLMD_DB_HOST)", + "--mysql_config_database=$(MYSQL_DATABASE)", + "--mysql_config_port=$(MYSQL_PORT)", + "--mysql_config_user=$(MYSQL_USER_NAME)", + "--mysql_config_password=$(MYSQL_ROOT_PASSWORD)"] diff --git a/manifests/kustomize/overlays/db/secrets.env b/manifests/kustomize/overlays/db/secrets.env new file mode 100644 index 00000000..44ac2ee3 --- /dev/null +++ b/manifests/kustomize/overlays/db/secrets.env @@ -0,0 +1,2 @@ +MYSQL_USER_NAME=root +MYSQL_ROOT_PASSWORD=test \ No newline at end of file diff --git a/manifests/kustomize/overlays/postgres/kustomization.yaml b/manifests/kustomize/overlays/postgres/kustomization.yaml new file mode 100644 index 00000000..facbb163 --- /dev/null +++ b/manifests/kustomize/overlays/postgres/kustomization.yaml @@ -0,0 +1,38 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kubeflow + +bases: +- ../../base +resources: +- model-registry-db-pvc.yaml +- model-registry-db-deployment.yaml +- model-registry-db-service.yaml + +patchesStrategicMerge: +- patches/model-registry-deployment.yaml + +configMapGenerator: +- name: metadata-postgres-db-parameters + envs: + - params.env +secretGenerator: +- name: metadata-postgres-db-secrets + envs: + - secrets.env +generatorOptions: + disableNameSuffixHash: true + +images: +- name: postgres + newName: postgres + newTag: 14.7-alpine3.17 + +vars: +- name: MLMD_DB_HOST + objref: + kind: Service + name: metadata-postgres-db + apiVersion: v1 + fieldref: + fieldpath: metadata.name diff --git a/manifests/kustomize/overlays/postgres/model-registry-db-deployment.yaml b/manifests/kustomize/overlays/postgres/model-registry-db-deployment.yaml new file mode 100644 index 00000000..061d109e --- /dev/null +++ b/manifests/kustomize/overlays/postgres/model-registry-db-deployment.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: metadata-postgres-db + labels: + component: db +spec: + selector: + matchLabels: + component: db + replicas: 1 + strategy: + type: Recreate + template: + metadata: + name: db + labels: + component: db + annotations: + sidecar.istio.io/inject: "false" + spec: + containers: + - name: db-container + image: postgres + env: + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + envFrom: + - configMapRef: + name: metadata-postgres-db-parameters + - secretRef: + name: metadata-postgres-db-secrets + ports: + - name: postgres + containerPort: 5432 + volumeMounts: + - name: metadata-postgres + mountPath: /var/lib/postgresql/data + volumes: + - name: metadata-postgres + persistentVolumeClaim: + claimName: metadata-postgres + diff --git a/manifests/kustomize/overlays/postgres/model-registry-db-pvc.yaml b/manifests/kustomize/overlays/postgres/model-registry-db-pvc.yaml new file mode 100644 index 00000000..13790489 --- /dev/null +++ b/manifests/kustomize/overlays/postgres/model-registry-db-pvc.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: metadata-postgres +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 20Gi diff --git a/manifests/kustomize/overlays/postgres/model-registry-db-service.yaml b/manifests/kustomize/overlays/postgres/model-registry-db-service.yaml new file mode 100644 index 00000000..63902a66 --- /dev/null +++ b/manifests/kustomize/overlays/postgres/model-registry-db-service.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: metadata-postgres-db + labels: + component: db +spec: + type: ClusterIP + ports: + - port: 5432 + protocol: TCP + name: postgres + selector: + component: db diff --git a/manifests/kustomize/overlays/postgres/params.env b/manifests/kustomize/overlays/postgres/params.env new file mode 100644 index 00000000..fce7e267 --- /dev/null +++ b/manifests/kustomize/overlays/postgres/params.env @@ -0,0 +1,2 @@ +POSTGRES_PORT=5432 +POSTGRES_DBNAME=mlmdpostgres \ No newline at end of file diff --git a/manifests/kustomize/overlays/postgres/patches/model-registry-deployment.yaml b/manifests/kustomize/overlays/postgres/patches/model-registry-deployment.yaml new file mode 100644 index 00000000..a97fc2a9 --- /dev/null +++ b/manifests/kustomize/overlays/postgres/patches/model-registry-deployment.yaml @@ -0,0 +1,28 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: model-registry-deployment +spec: + template: + spec: + containers: + - name: grpc-container + # Remove existing environment variables + env: + - $patch: replace + envFrom: + - configMapRef: + name: metadata-postgres-db-parameters + - secretRef: + name: metadata-postgres-db-secrets + - configMapRef: + name: model-registry-configmap + args: ["--grpc_port=$(MODEL_REGISTRY_GRPC_SERVICE_PORT)", + "--metadata_source_config_type=postgresql", + "--postgres_config_host=$(MLMD_DB_HOST)", + "--postgres_config_port=$(POSTGRES_PORT)", + "--postgres_config_dbname=$(POSTGRES_DBNAME)", + "--postgres_config_user=$(POSTGRES_USER)", + "--postgres_config_password=$(POSTGRES_PASSWORD)", + # "--postgres_config_skip_db_creation=true", + "--enable_database_upgrade=true"] diff --git a/manifests/kustomize/overlays/postgres/secrets.env b/manifests/kustomize/overlays/postgres/secrets.env new file mode 100644 index 00000000..973d1582 --- /dev/null +++ b/manifests/kustomize/overlays/postgres/secrets.env @@ -0,0 +1,2 @@ +POSTGRES_USER=root +POSTGRES_PASSWORD=password \ No newline at end of file From 54b3792299a6d9dcdb6da8a0139c4fe089575616 Mon Sep 17 00:00:00 2001 From: Dhiraj Bokde Date: Mon, 19 Feb 2024 11:01:53 -0800 Subject: [PATCH 254/254] fix: istio manifest cleanup, fixes RHOAIENG-1947 (#318) --- .github/workflows/build-image-pr.yml | 9 +-------- manifests/kustomize/base/kustomization.yaml | 3 --- .../options/istio/virtual-service.yaml | 18 +++++++++++------- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-image-pr.yml b/.github/workflows/build-image-pr.yml index ce4b2e7f..1c3cc003 100644 --- a/.github/workflows/build-image-pr.yml +++ b/.github/workflows/build-image-pr.yml @@ -50,12 +50,5 @@ jobs: kubectl apply -k "https://github.com/opendatahub-io/model-registry-operator.git/config/samples?ref=${BRANCH}" kubectl get mr - name: Wait for Test Registry Deployment - timeout-minutes: 5 run: | - CONDITION="false" - while [ "${CONDITION}" != "True" ] - do - sleep 5 - CONDITION="`kubectl get mr modelregistry-sample --output=jsonpath='{.status.conditions[?(@.type=="Available")].status}'`" - echo "Registry Available=${CONDITION}" - done + kubectl wait --for=condition=Available=true modelregistries/modelregistry-sample --timeout=5m diff --git a/manifests/kustomize/base/kustomization.yaml b/manifests/kustomize/base/kustomization.yaml index 5d497c83..bf9c0720 100644 --- a/manifests/kustomize/base/kustomization.yaml +++ b/manifests/kustomize/base/kustomization.yaml @@ -5,6 +5,3 @@ resources: - model-registry-deployment.yaml - model-registry-service.yaml - model-registry-sa.yaml -images: - - name: gcr.io/ml-pipeline/metadata-envoy - newTag: 2.0.5 diff --git a/manifests/kustomize/options/istio/virtual-service.yaml b/manifests/kustomize/options/istio/virtual-service.yaml index 1cbdaeb2..3544365e 100644 --- a/manifests/kustomize/options/istio/virtual-service.yaml +++ b/manifests/kustomize/options/istio/virtual-service.yaml @@ -8,14 +8,18 @@ spec: - kubeflow-gateway hosts: - '*' - http: + tcp: - match: - - uri: - prefix: /ml_metadata - rewrite: - uri: /ml_metadata + - port: 8080 route: - destination: - host: metadata-envoy-service.kubeflow.svc.cluster.local + host: model-registry-service.kubeflow.svc.cluster.local port: - number: 9090 + number: 8080 + - match: + - port: 9090 + route: + - destination: + host: model-registry-service.kubeflow.svc.cluster.local + port: + number: 9090

?nLv% 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≀ik^Gcz2p6iJyR;#lxY75`;BW)WN_obEr04 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%0DNL={`P0yn{vl&z-SnB9S;0)! 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�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 z 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 z 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