diff --git a/.gitignore b/.gitignore index 74d6f3b..77f3986 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +.vscode/* + # The directory Mix will write compiled artifacts to. /_build/ diff --git a/Makefile b/Makefile index 77bf7ea..0ba1d16 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -image=eigr/massa-proxy:0.1.36 +image=eigr/massa-proxy:1.0.0-PREVIEW port=8080 .PHONY: all clean diff --git a/apps/cloudstate_protocol/lib/cloudstate/entity_key.pb.ex b/apps/cloudstate_protocol/lib/cloudstate/entity_key.pb.ex index 4b03647..e69de29 100644 --- a/apps/cloudstate_protocol/lib/cloudstate/entity_key.pb.ex +++ b/apps/cloudstate_protocol/lib/cloudstate/entity_key.pb.ex @@ -1,5 +0,0 @@ -defmodule Cloudstate.PbExtension do - @moduledoc false - use Protobuf, syntax: :proto3 - extend(Google.Protobuf.FieldOptions, :entity_key, 1080, optional: true, type: :bool) -end diff --git a/apps/cloudstate_protocol/lib/cloudstate/eventing.pb.ex b/apps/cloudstate_protocol/lib/cloudstate/eventing.pb.ex index 663a009..a767df1 100644 --- a/apps/cloudstate_protocol/lib/cloudstate/eventing.pb.ex +++ b/apps/cloudstate_protocol/lib/cloudstate/eventing.pb.ex @@ -6,7 +6,6 @@ defmodule Cloudstate.Eventing do in: Cloudstate.EventSource.t() | nil, out: Cloudstate.EventDestination.t() | nil } - defstruct [:in, :out] def descriptor do @@ -20,8 +19,8 @@ defmodule Cloudstate.Eventing do ) end - field(:in, 1, type: Cloudstate.EventSource) - field(:out, 2, type: Cloudstate.EventDestination) + field :in, 1, type: Cloudstate.EventSource + field :out, 2, type: Cloudstate.EventDestination end defmodule Cloudstate.EventSource do @@ -32,7 +31,6 @@ defmodule Cloudstate.EventSource do source: {atom, any}, consumer_group: String.t() } - defstruct [:source, :consumer_group] def descriptor do @@ -47,11 +45,10 @@ defmodule Cloudstate.EventSource do ) end - oneof(:source, 0) - - field(:consumer_group, 1, type: :string) - field(:topic, 2, type: :string, oneof: 0) - field(:event_log, 3, type: :string, oneof: 0) + oneof :source, 0 + field :consumer_group, 1, type: :string + field :topic, 2, type: :string, oneof: 0 + field :event_log, 3, type: :string, oneof: 0 end defmodule Cloudstate.EventDestination do @@ -61,7 +58,6 @@ defmodule Cloudstate.EventDestination do @type t :: %__MODULE__{ destination: {atom, any} } - defstruct [:destination] def descriptor do @@ -73,14 +69,6 @@ defmodule Cloudstate.EventDestination do ) end - oneof(:destination, 0) - - field(:topic, 1, type: :string, oneof: 0) -end - -defmodule Cloudstate.PbExtension do - @moduledoc false - use Protobuf, syntax: :proto3 - - extend(Google.Protobuf.MethodOptions, :eventing, 1081, optional: true, type: Cloudstate.Eventing) + oneof :destination, 0 + field :topic, 1, type: :string, oneof: 0 end diff --git a/apps/cloudstate_protocol/lib/google/api/annotations.pb.ex b/apps/cloudstate_protocol/lib/google/api/annotations.pb.ex index 2aa2341..e69de29 100644 --- a/apps/cloudstate_protocol/lib/google/api/annotations.pb.ex +++ b/apps/cloudstate_protocol/lib/google/api/annotations.pb.ex @@ -1,9 +0,0 @@ -defmodule Google.Api.PbExtension do - @moduledoc false - use Protobuf, syntax: :proto3 - - extend(Google.Protobuf.MethodOptions, :http, 72_295_728, - optional: true, - type: Google.Api.HttpRule - ) -end diff --git a/apps/cloudstate_protocol/lib/google/api/auth.pb.ex b/apps/cloudstate_protocol/lib/google/api/auth.pb.ex index 0e66549..f2a05b9 100644 --- a/apps/cloudstate_protocol/lib/google/api/auth.pb.ex +++ b/apps/cloudstate_protocol/lib/google/api/auth.pb.ex @@ -6,7 +6,6 @@ defmodule Google.Api.Authentication do rules: [Google.Api.AuthenticationRule.t()], providers: [Google.Api.AuthProvider.t()] } - defstruct [:rules, :providers] def descriptor do @@ -22,8 +21,8 @@ defmodule Google.Api.Authentication do ) end - field(:rules, 3, repeated: true, type: Google.Api.AuthenticationRule) - field(:providers, 4, repeated: true, type: Google.Api.AuthProvider) + field :rules, 3, repeated: true, type: Google.Api.AuthenticationRule + field :providers, 4, repeated: true, type: Google.Api.AuthProvider end defmodule Google.Api.AuthenticationRule do @@ -36,7 +35,6 @@ defmodule Google.Api.AuthenticationRule do allow_without_credential: boolean, requirements: [Google.Api.AuthRequirement.t()] } - defstruct [:selector, :oauth, :allow_without_credential, :requirements] def descriptor do @@ -57,10 +55,10 @@ defmodule Google.Api.AuthenticationRule do ) end - field(:selector, 1, type: :string) - field(:oauth, 2, type: Google.Api.OAuthRequirements) - field(:allow_without_credential, 5, type: :bool) - field(:requirements, 7, repeated: true, type: Google.Api.AuthRequirement) + field :selector, 1, type: :string + field :oauth, 2, type: Google.Api.OAuthRequirements + field :allow_without_credential, 5, type: :bool + field :requirements, 7, repeated: true, type: Google.Api.AuthRequirement end defmodule Google.Api.JwtLocation do @@ -71,7 +69,6 @@ defmodule Google.Api.JwtLocation do in: {atom, any}, value_prefix: String.t() } - defstruct [:in, :value_prefix] def descriptor do @@ -86,11 +83,10 @@ defmodule Google.Api.JwtLocation do ) end - oneof(:in, 0) - - field(:header, 1, type: :string, oneof: 0) - field(:query, 2, type: :string, oneof: 0) - field(:value_prefix, 3, type: :string) + oneof :in, 0 + field :header, 1, type: :string, oneof: 0 + field :query, 2, type: :string, oneof: 0 + field :value_prefix, 3, type: :string end defmodule Google.Api.AuthProvider do @@ -105,7 +101,6 @@ defmodule Google.Api.AuthProvider do authorization_url: String.t(), jwt_locations: [Google.Api.JwtLocation.t()] } - defstruct [:id, :issuer, :jwks_uri, :audiences, :authorization_url, :jwt_locations] def descriptor do @@ -125,12 +120,12 @@ defmodule Google.Api.AuthProvider do ) end - field(:id, 1, type: :string) - field(:issuer, 2, type: :string) - field(:jwks_uri, 3, type: :string) - field(:audiences, 4, type: :string) - field(:authorization_url, 5, type: :string) - field(:jwt_locations, 6, repeated: true, type: Google.Api.JwtLocation) + field :id, 1, type: :string + field :issuer, 2, type: :string + field :jwks_uri, 3, type: :string + field :audiences, 4, type: :string + field :authorization_url, 5, type: :string + field :jwt_locations, 6, repeated: true, type: Google.Api.JwtLocation end defmodule Google.Api.OAuthRequirements do @@ -140,7 +135,6 @@ defmodule Google.Api.OAuthRequirements do @type t :: %__MODULE__{ canonical_scopes: String.t() } - defstruct [:canonical_scopes] def descriptor do @@ -153,7 +147,7 @@ defmodule Google.Api.OAuthRequirements do ) end - field(:canonical_scopes, 1, type: :string) + field :canonical_scopes, 1, type: :string end defmodule Google.Api.AuthRequirement do @@ -164,7 +158,6 @@ defmodule Google.Api.AuthRequirement do provider_id: String.t(), audiences: String.t() } - defstruct [:provider_id, :audiences] def descriptor do @@ -177,6 +170,6 @@ defmodule Google.Api.AuthRequirement do ) end - field(:provider_id, 1, type: :string) - field(:audiences, 2, type: :string) + field :provider_id, 1, type: :string + field :audiences, 2, type: :string end diff --git a/apps/cloudstate_protocol/lib/google/api/http.pb.ex b/apps/cloudstate_protocol/lib/google/api/http.pb.ex index 59bd841..ba11776 100644 --- a/apps/cloudstate_protocol/lib/google/api/http.pb.ex +++ b/apps/cloudstate_protocol/lib/google/api/http.pb.ex @@ -6,7 +6,6 @@ defmodule Google.Api.Http do rules: [Google.Api.HttpRule.t()], fully_decode_reserved_expansion: boolean } - defstruct [:rules, :fully_decode_reserved_expansion] def descriptor do @@ -22,8 +21,8 @@ defmodule Google.Api.Http do ) end - field(:rules, 1, repeated: true, type: Google.Api.HttpRule) - field(:fully_decode_reserved_expansion, 2, type: :bool) + field :rules, 1, repeated: true, type: Google.Api.HttpRule + field :fully_decode_reserved_expansion, 2, type: :bool end defmodule Google.Api.HttpRule do @@ -37,7 +36,6 @@ defmodule Google.Api.HttpRule do response_body: String.t(), additional_bindings: [Google.Api.HttpRule.t()] } - defstruct [:pattern, :selector, :body, :response_body, :additional_bindings] def descriptor do @@ -63,18 +61,17 @@ defmodule Google.Api.HttpRule do ) end - oneof(:pattern, 0) - - field(:selector, 1, type: :string) - field(:get, 2, type: :string, oneof: 0) - field(:put, 3, type: :string, oneof: 0) - field(:post, 4, type: :string, oneof: 0) - field(:delete, 5, type: :string, oneof: 0) - field(:patch, 6, type: :string, oneof: 0) - field(:custom, 8, type: Google.Api.CustomHttpPattern, oneof: 0) - field(:body, 7, type: :string) - field(:response_body, 12, type: :string) - field(:additional_bindings, 11, repeated: true, type: Google.Api.HttpRule) + oneof :pattern, 0 + field :selector, 1, type: :string + field :get, 2, type: :string, oneof: 0 + field :put, 3, type: :string, oneof: 0 + field :post, 4, type: :string, oneof: 0 + field :delete, 5, type: :string, oneof: 0 + field :patch, 6, type: :string, oneof: 0 + field :custom, 8, type: Google.Api.CustomHttpPattern, oneof: 0 + field :body, 7, type: :string + field :response_body, 12, type: :string + field :additional_bindings, 11, repeated: true, type: Google.Api.HttpRule end defmodule Google.Api.CustomHttpPattern do @@ -85,7 +82,6 @@ defmodule Google.Api.CustomHttpPattern do kind: String.t(), path: String.t() } - defstruct [:kind, :path] def descriptor do @@ -97,6 +93,6 @@ defmodule Google.Api.CustomHttpPattern do ) end - field(:kind, 1, type: :string) - field(:path, 2, type: :string) + field :kind, 1, type: :string + field :path, 2, type: :string end diff --git a/apps/cloudstate_protocol/lib/google/api/httpbody.pb.ex b/apps/cloudstate_protocol/lib/google/api/httpbody.pb.ex index 2a435a7..fe675e8 100644 --- a/apps/cloudstate_protocol/lib/google/api/httpbody.pb.ex +++ b/apps/cloudstate_protocol/lib/google/api/httpbody.pb.ex @@ -7,7 +7,6 @@ defmodule Google.Api.HttpBody do data: binary, extensions: [Google.Protobuf.Any.t()] } - defstruct [:content_type, :data, :extensions] def descriptor do @@ -22,7 +21,7 @@ defmodule Google.Api.HttpBody do ) end - field(:content_type, 1, type: :string) - field(:data, 2, type: :bytes) - field(:extensions, 3, repeated: true, type: Google.Protobuf.Any) + field :content_type, 1, type: :string + field :data, 2, type: :bytes + field :extensions, 3, repeated: true, type: Google.Protobuf.Any end diff --git a/apps/cloudstate_protocol/lib/google/api/source_info.pb.ex b/apps/cloudstate_protocol/lib/google/api/source_info.pb.ex index 9c64ca0..c2121b0 100644 --- a/apps/cloudstate_protocol/lib/google/api/source_info.pb.ex +++ b/apps/cloudstate_protocol/lib/google/api/source_info.pb.ex @@ -5,7 +5,6 @@ defmodule Google.Api.SourceInfo do @type t :: %__MODULE__{ source_files: [Google.Protobuf.Any.t()] } - defstruct [:source_files] def descriptor do @@ -18,5 +17,5 @@ defmodule Google.Api.SourceInfo do ) end - field(:source_files, 1, repeated: true, type: Google.Protobuf.Any) + field :source_files, 1, repeated: true, type: Google.Protobuf.Any end diff --git a/apps/cloudstate_protocol/lib/grpc/reflection/v1alpha/reflection.pb.ex b/apps/cloudstate_protocol/lib/grpc/reflection/v1alpha/reflection.pb.ex index 969cd6f..9fb40bc 100644 --- a/apps/cloudstate_protocol/lib/grpc/reflection/v1alpha/reflection.pb.ex +++ b/apps/cloudstate_protocol/lib/grpc/reflection/v1alpha/reflection.pb.ex @@ -6,7 +6,6 @@ defmodule Grpc.Reflection.V1alpha.ServerReflectionRequest do message_request: {atom, any}, host: String.t() } - defstruct [:message_request, :host] def descriptor do @@ -35,14 +34,13 @@ defmodule Grpc.Reflection.V1alpha.ServerReflectionRequest do ) end - oneof(:message_request, 0) - - field(:host, 1, type: :string) - field(:file_by_filename, 3, type: :string, oneof: 0) - field(:file_containing_symbol, 4, type: :string, oneof: 0) - field(:file_containing_extension, 5, type: Grpc.Reflection.V1alpha.ExtensionRequest, oneof: 0) - field(:all_extension_numbers_of_type, 6, type: :string, oneof: 0) - field(:list_services, 7, type: :string, oneof: 0) + oneof :message_request, 0 + field :host, 1, type: :string + field :file_by_filename, 3, type: :string, oneof: 0 + field :file_containing_symbol, 4, type: :string, oneof: 0 + field :file_containing_extension, 5, type: Grpc.Reflection.V1alpha.ExtensionRequest, oneof: 0 + field :all_extension_numbers_of_type, 6, type: :string, oneof: 0 + field :list_services, 7, type: :string, oneof: 0 end defmodule Grpc.Reflection.V1alpha.ExtensionRequest do @@ -53,7 +51,6 @@ defmodule Grpc.Reflection.V1alpha.ExtensionRequest do containing_type: String.t(), extension_number: integer } - defstruct [:containing_type, :extension_number] def descriptor do @@ -68,8 +65,8 @@ defmodule Grpc.Reflection.V1alpha.ExtensionRequest do ) end - field(:containing_type, 1, type: :string) - field(:extension_number, 2, type: :int32) + field :containing_type, 1, type: :string + field :extension_number, 2, type: :int32 end defmodule Grpc.Reflection.V1alpha.ServerReflectionResponse do @@ -81,7 +78,6 @@ defmodule Grpc.Reflection.V1alpha.ServerReflectionResponse do valid_host: String.t(), original_request: Grpc.Reflection.V1alpha.ServerReflectionRequest.t() | nil } - defstruct [:message_response, :valid_host, :original_request] def descriptor do @@ -121,23 +117,20 @@ defmodule Grpc.Reflection.V1alpha.ServerReflectionResponse do ) end - oneof(:message_response, 0) - - field(:valid_host, 1, type: :string) - field(:original_request, 2, type: Grpc.Reflection.V1alpha.ServerReflectionRequest) + oneof :message_response, 0 + field :valid_host, 1, type: :string + field :original_request, 2, type: Grpc.Reflection.V1alpha.ServerReflectionRequest - field(:file_descriptor_response, 4, + field :file_descriptor_response, 4, type: Grpc.Reflection.V1alpha.FileDescriptorResponse, oneof: 0 - ) - field(:all_extension_numbers_response, 5, + field :all_extension_numbers_response, 5, type: Grpc.Reflection.V1alpha.ExtensionNumberResponse, oneof: 0 - ) - field(:list_services_response, 6, type: Grpc.Reflection.V1alpha.ListServiceResponse, oneof: 0) - field(:error_response, 7, type: Grpc.Reflection.V1alpha.ErrorResponse, oneof: 0) + field :list_services_response, 6, type: Grpc.Reflection.V1alpha.ListServiceResponse, oneof: 0 + field :error_response, 7, type: Grpc.Reflection.V1alpha.ErrorResponse, oneof: 0 end defmodule Grpc.Reflection.V1alpha.FileDescriptorResponse do @@ -147,7 +140,6 @@ defmodule Grpc.Reflection.V1alpha.FileDescriptorResponse do @type t :: %__MODULE__{ file_descriptor_proto: [binary] } - defstruct [:file_descriptor_proto] def descriptor do @@ -160,7 +152,7 @@ defmodule Grpc.Reflection.V1alpha.FileDescriptorResponse do ) end - field(:file_descriptor_proto, 1, repeated: true, type: :bytes) + field :file_descriptor_proto, 1, repeated: true, type: :bytes end defmodule Grpc.Reflection.V1alpha.ExtensionNumberResponse do @@ -171,7 +163,6 @@ defmodule Grpc.Reflection.V1alpha.ExtensionNumberResponse do base_type_name: String.t(), extension_number: [integer] } - defstruct [:base_type_name, :extension_number] def descriptor do @@ -186,8 +177,8 @@ defmodule Grpc.Reflection.V1alpha.ExtensionNumberResponse do ) end - field(:base_type_name, 1, type: :string) - field(:extension_number, 2, repeated: true, type: :int32) + field :base_type_name, 1, type: :string + field :extension_number, 2, repeated: true, type: :int32 end defmodule Grpc.Reflection.V1alpha.ListServiceResponse do @@ -197,7 +188,6 @@ defmodule Grpc.Reflection.V1alpha.ListServiceResponse do @type t :: %__MODULE__{ service: [Grpc.Reflection.V1alpha.ServiceResponse.t()] } - defstruct [:service] def descriptor do @@ -211,7 +201,7 @@ defmodule Grpc.Reflection.V1alpha.ListServiceResponse do ) end - field(:service, 1, repeated: true, type: Grpc.Reflection.V1alpha.ServiceResponse) + field :service, 1, repeated: true, type: Grpc.Reflection.V1alpha.ServiceResponse end defmodule Grpc.Reflection.V1alpha.ServiceResponse do @@ -221,7 +211,6 @@ defmodule Grpc.Reflection.V1alpha.ServiceResponse do @type t :: %__MODULE__{ name: String.t() } - defstruct [:name] def descriptor do @@ -232,7 +221,7 @@ defmodule Grpc.Reflection.V1alpha.ServiceResponse do ) end - field(:name, 1, type: :string) + field :name, 1, type: :string end defmodule Grpc.Reflection.V1alpha.ErrorResponse do @@ -243,7 +232,6 @@ defmodule Grpc.Reflection.V1alpha.ErrorResponse do error_code: integer, error_message: String.t() } - defstruct [:error_code, :error_message] def descriptor do @@ -257,8 +245,8 @@ defmodule Grpc.Reflection.V1alpha.ErrorResponse do ) end - field(:error_code, 1, type: :int32) - field(:error_message, 2, type: :string) + field :error_code, 1, type: :int32 + field :error_message, 2, type: :string end defmodule Grpc.Reflection.V1alpha.ServerReflection.Service do @@ -279,11 +267,9 @@ defmodule Grpc.Reflection.V1alpha.ServerReflection.Service do ) end - rpc( - :ServerReflectionInfo, - stream(Grpc.Reflection.V1alpha.ServerReflectionRequest), - stream(Grpc.Reflection.V1alpha.ServerReflectionResponse) - ) + rpc :ServerReflectionInfo, + stream(Grpc.Reflection.V1alpha.ServerReflectionRequest), + stream(Grpc.Reflection.V1alpha.ServerReflectionResponse) end defmodule Grpc.Reflection.V1alpha.ServerReflection.Stub do diff --git a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/function.proto b/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/function.proto deleted file mode 100644 index d0e54ea..0000000 --- a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/function.proto +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2019 Lightbend Inc. -// -// 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. - -// gRPC interface for Stateless Entity user functions. - -syntax = "proto3"; - -package cloudstate.function; - -// Any is used so that domain events defined according to the functions business domain can be embedded inside -// the protocol. -import "google/protobuf/any.proto"; -import "cloudstate/entity.proto"; - -option java_package = "io.cloudstate.protocol"; -option go_package = "cloudstate/protocol"; - -message FunctionCommand { - // The name of the service this function is on. - string service_name = 2; - - // Command name - string name = 3; - - // The command payload. - google.protobuf.Any payload = 4; -} - -message FunctionReply { - - oneof response { - Failure failure = 1; - Reply reply = 2; - Forward forward = 3; - } - - repeated SideEffect side_effects = 4; -} - -service StatelessFunction { - - rpc handleUnary(FunctionCommand) returns (FunctionReply) {} - - rpc handleStreamedIn(stream FunctionCommand) returns (FunctionReply) {} - - rpc handleStreamedOut(FunctionCommand) returns (stream FunctionReply) {} - - rpc handleStreamed(stream FunctionCommand) returns (stream FunctionReply) {} - -} diff --git a/apps/eigr_protocol/.formatter.exs b/apps/eigr_protocol/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/apps/eigr_protocol/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/apps/eigr_protocol/.gitignore b/apps/eigr_protocol/.gitignore new file mode 100644 index 0000000..7483f11 --- /dev/null +++ b/apps/eigr_protocol/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +eigr_protocol-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/apps/eigr_protocol/README.md b/apps/eigr_protocol/README.md new file mode 100644 index 0000000..b14e6f0 --- /dev/null +++ b/apps/eigr_protocol/README.md @@ -0,0 +1,21 @@ +# EigrProtocol + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `eigr_protocol` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:eigr_protocol, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/apps/eigr_protocol/compile-pb.sh b/apps/eigr_protocol/compile-pb.sh new file mode 100755 index 0000000..f02c657 --- /dev/null +++ b/apps/eigr_protocol/compile-pb.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -o nounset +set -o errexit +set -o pipefail + +# CloudState Protocol + +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib --proto_path=priv/protos/eigr/functions/proxy/ priv/protos/eigr/functions/proxy/grpc/reflection/v1alpha/reflection.proto + +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib --proto_path=priv/protos/eigr/functions/frontend/ priv/protos/eigr/functions/frontend/google/api/http.proto +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib --proto_path=priv/protos/eigr/functions/frontend/ priv/protos/eigr/functions/frontend/google/api/annotations.proto +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib --proto_path=priv/protos/eigr/functions/frontend/ priv/protos/eigr/functions/frontend/google/api/httpbody.proto +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib --proto_path=priv/protos/eigr/functions/frontend/ priv/protos/eigr/functions/frontend/google/api/auth.proto +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib --proto_path=priv/protos/eigr/functions/frontend/ priv/protos/eigr/functions/frontend/google/api/source_info.proto + +protoc --elixir_out=gen_descriptors=true:./lib/eigr/functions/protocol --proto_path=priv/protos/eigr/functions/protocol/eigr/ priv/protos/eigr/functions/protocol/eigr/eventing.proto +protoc --elixir_out=gen_descriptors=true:./lib/eigr/functions/protocol --proto_path=priv/protos/eigr/functions/protocol/eigr/ priv/protos/eigr/functions/protocol/eigr/entity_key.proto + +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib/eigr/functions/protocol --proto_path=priv/protos/eigr/functions/protocol/eigr/ priv/protos/eigr/functions/protocol/eigr/entity.proto +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib/eigr/functions/protocol --proto_path=priv/protos/eigr/functions/protocol/eigr/ priv/protos/eigr/functions/protocol/eigr/event_sourced.proto +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib/eigr/functions/protocol --proto_path=priv/protos/eigr/functions/protocol/eigr/ priv/protos/eigr/functions/protocol/eigr/action.proto +protoc --elixir_out=gen_descriptors=true,plugins=grpc:./lib/eigr/functions/protocol --proto_path=priv/protos/eigr/functions/protocol/eigr/ priv/protos/eigr/functions/protocol/eigr/value_entity.proto diff --git a/apps/eigr_protocol/fetch-cloudstate-pb.sh b/apps/eigr_protocol/fetch-cloudstate-pb.sh new file mode 100755 index 0000000..371ac82 --- /dev/null +++ b/apps/eigr_protocol/fetch-cloudstate-pb.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash + +set -o nounset +set -o errexit +set -o pipefail + +function fetch() { + local path=$1 + local tag=$2 + mkdir -p "priv/protos/$(dirname $path)" + curl -o "priv/protos/${path}" "https://raw.githubusercontent.com/cloudstateio/cloudstate/${tag}/protocols/${path}" +} + +tag=$1 + +# CloudState protocol +fetch "protocol/cloudstate/entity.proto" "${tag}" +fetch "protocol/cloudstate/event_sourced.proto" "${tag}" +fetch "protocol/cloudstate/function.proto" "${tag}" +fetch "protocol/cloudstate/crdt.proto" "${tag}" + +# TCK shopping cart example +fetch "example/shoppingcart/shoppingcart.proto" "${tag}" +fetch "example/shoppingcart/persistence/domain.proto" "${tag}" + +# CloudState frontend +fetch "frontend/cloudstate/entity_key.proto" "${tag}" + +# dependencies +fetch "proxy/grpc/reflection/v1alpha/reflection.proto" "${tag}" +fetch "frontend/google/api/annotations.proto" "${tag}" +fetch "frontend/google/api/http.proto" "${tag}" \ No newline at end of file diff --git a/apps/eigr_protocol/lib/cloudstate/entity_key.pb.ex b/apps/eigr_protocol/lib/cloudstate/entity_key.pb.ex new file mode 100644 index 0000000..e69de29 diff --git a/apps/eigr_protocol/lib/cloudstate/eventing.pb.ex b/apps/eigr_protocol/lib/cloudstate/eventing.pb.ex new file mode 100644 index 0000000..a767df1 --- /dev/null +++ b/apps/eigr_protocol/lib/cloudstate/eventing.pb.ex @@ -0,0 +1,74 @@ +defmodule Cloudstate.Eventing do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + in: Cloudstate.EventSource.t() | nil, + out: Cloudstate.EventDestination.t() | nil + } + defstruct [:in, :out] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 8, 69, 118, 101, 110, 116, 105, 110, 103, 18, 39, 10, 2, 105, 110, 24, 1, 32, 1, 40, + 11, 50, 23, 46, 99, 108, 111, 117, 100, 115, 116, 97, 116, 101, 46, 69, 118, 101, 110, + 116, 83, 111, 117, 114, 99, 101, 82, 2, 105, 110, 18, 46, 10, 3, 111, 117, 116, 24, 2, 32, + 1, 40, 11, 50, 28, 46, 99, 108, 111, 117, 100, 115, 116, 97, 116, 101, 46, 69, 118, 101, + 110, 116, 68, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110, 82, 3, 111, 117, 116>> + ) + end + + field :in, 1, type: Cloudstate.EventSource + field :out, 2, type: Cloudstate.EventDestination +end + +defmodule Cloudstate.EventSource do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + source: {atom, any}, + consumer_group: String.t() + } + defstruct [:source, :consumer_group] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 11, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 18, 37, 10, 14, 99, 111, 110, + 115, 117, 109, 101, 114, 95, 103, 114, 111, 117, 112, 24, 1, 32, 1, 40, 9, 82, 13, 99, + 111, 110, 115, 117, 109, 101, 114, 71, 114, 111, 117, 112, 18, 22, 10, 5, 116, 111, 112, + 105, 99, 24, 2, 32, 1, 40, 9, 72, 0, 82, 5, 116, 111, 112, 105, 99, 18, 29, 10, 9, 101, + 118, 101, 110, 116, 95, 108, 111, 103, 24, 3, 32, 1, 40, 9, 72, 0, 82, 8, 101, 118, 101, + 110, 116, 76, 111, 103, 66, 8, 10, 6, 115, 111, 117, 114, 99, 101>> + ) + end + + oneof :source, 0 + field :consumer_group, 1, type: :string + field :topic, 2, type: :string, oneof: 0 + field :event_log, 3, type: :string, oneof: 0 +end + +defmodule Cloudstate.EventDestination do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + destination: {atom, any} + } + defstruct [:destination] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 16, 69, 118, 101, 110, 116, 68, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110, 18, + 22, 10, 5, 116, 111, 112, 105, 99, 24, 1, 32, 1, 40, 9, 72, 0, 82, 5, 116, 111, 112, 105, + 99, 66, 13, 10, 11, 100, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110>> + ) + end + + oneof :destination, 0 + field :topic, 1, type: :string, oneof: 0 +end diff --git a/apps/eigr_protocol/lib/eigr/functions/protocol/action.pb.ex b/apps/eigr_protocol/lib/eigr/functions/protocol/action.pb.ex new file mode 100644 index 0000000..4d53b06 --- /dev/null +++ b/apps/eigr_protocol/lib/eigr/functions/protocol/action.pb.ex @@ -0,0 +1,129 @@ +defmodule Eigr.Functions.Protocol.Action.ActionCommand do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + service_name: String.t(), + name: String.t(), + payload: Google.Protobuf.Any.t() | nil, + metadata: Eigr.Functions.Protocol.Metadata.t() | nil + } + defstruct [:service_name, :name, :payload, :metadata] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 13, 65, 99, 116, 105, 111, 110, 67, 111, 109, 109, 97, 110, 100, 18, 33, 10, 12, 115, + 101, 114, 118, 105, 99, 101, 95, 110, 97, 109, 101, 24, 2, 32, 1, 40, 9, 82, 11, 115, 101, + 114, 118, 105, 99, 101, 78, 97, 109, 101, 18, 18, 10, 4, 110, 97, 109, 101, 24, 3, 32, 1, + 40, 9, 82, 4, 110, 97, 109, 101, 18, 46, 10, 7, 112, 97, 121, 108, 111, 97, 100, 24, 4, + 32, 1, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, + 117, 102, 46, 65, 110, 121, 82, 7, 112, 97, 121, 108, 111, 97, 100, 18, 61, 10, 8, 109, + 101, 116, 97, 100, 97, 116, 97, 24, 5, 32, 1, 40, 11, 50, 33, 46, 101, 105, 103, 114, 46, + 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, + 77, 101, 116, 97, 100, 97, 116, 97, 82, 8, 109, 101, 116, 97, 100, 97, 116, 97>> + ) + end + + field :service_name, 2, type: :string + field :name, 3, type: :string + field :payload, 4, type: Google.Protobuf.Any + field :metadata, 5, type: Eigr.Functions.Protocol.Metadata +end + +defmodule Eigr.Functions.Protocol.Action.ActionResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + response: {atom, any}, + side_effects: [Eigr.Functions.Protocol.SideEffect.t()] + } + defstruct [:response, :side_effects] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 14, 65, 99, 116, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 18, 60, 10, 7, + 102, 97, 105, 108, 117, 114, 101, 24, 1, 32, 1, 40, 11, 50, 32, 46, 101, 105, 103, 114, + 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, + 46, 70, 97, 105, 108, 117, 114, 101, 72, 0, 82, 7, 102, 97, 105, 108, 117, 114, 101, 18, + 54, 10, 5, 114, 101, 112, 108, 121, 24, 2, 32, 1, 40, 11, 50, 30, 46, 101, 105, 103, 114, + 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, + 46, 82, 101, 112, 108, 121, 72, 0, 82, 5, 114, 101, 112, 108, 121, 18, 60, 10, 7, 102, + 111, 114, 119, 97, 114, 100, 24, 3, 32, 1, 40, 11, 50, 32, 46, 101, 105, 103, 114, 46, + 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, + 70, 111, 114, 119, 97, 114, 100, 72, 0, 82, 7, 102, 111, 114, 119, 97, 114, 100, 18, 70, + 10, 12, 115, 105, 100, 101, 95, 101, 102, 102, 101, 99, 116, 115, 24, 4, 32, 3, 40, 11, + 50, 35, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, + 114, 111, 116, 111, 99, 111, 108, 46, 83, 105, 100, 101, 69, 102, 102, 101, 99, 116, 82, + 11, 115, 105, 100, 101, 69, 102, 102, 101, 99, 116, 115, 66, 10, 10, 8, 114, 101, 115, + 112, 111, 110, 115, 101>> + ) + end + + oneof :response, 0 + field :failure, 1, type: Eigr.Functions.Protocol.Failure, oneof: 0 + field :reply, 2, type: Eigr.Functions.Protocol.Reply, oneof: 0 + field :forward, 3, type: Eigr.Functions.Protocol.Forward, oneof: 0 + field :side_effects, 4, repeated: true, type: Eigr.Functions.Protocol.SideEffect +end + +defmodule Eigr.Functions.Protocol.Action.ActionProtocol.Service do + @moduledoc false + use GRPC.Service, name: "eigr.functions.protocol.action.ActionProtocol" + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.ServiceDescriptorProto.decode( + <<10, 14, 65, 99, 116, 105, 111, 110, 80, 114, 111, 116, 111, 99, 111, 108, 18, 117, 10, 11, + 104, 97, 110, 100, 108, 101, 85, 110, 97, 114, 121, 18, 45, 46, 101, 105, 103, 114, 46, + 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, + 97, 99, 116, 105, 111, 110, 46, 65, 99, 116, 105, 111, 110, 67, 111, 109, 109, 97, 110, + 100, 26, 46, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, + 112, 114, 111, 116, 111, 99, 111, 108, 46, 97, 99, 116, 105, 111, 110, 46, 65, 99, 116, + 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 3, 136, 2, 0, 40, 0, 48, 0, 18, + 122, 10, 16, 104, 97, 110, 100, 108, 101, 83, 116, 114, 101, 97, 109, 101, 100, 73, 110, + 18, 45, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, + 114, 111, 116, 111, 99, 111, 108, 46, 97, 99, 116, 105, 111, 110, 46, 65, 99, 116, 105, + 111, 110, 67, 111, 109, 109, 97, 110, 100, 26, 46, 46, 101, 105, 103, 114, 46, 102, 117, + 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 97, 99, + 116, 105, 111, 110, 46, 65, 99, 116, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, + 34, 3, 136, 2, 0, 40, 1, 48, 0, 18, 123, 10, 17, 104, 97, 110, 100, 108, 101, 83, 116, + 114, 101, 97, 109, 101, 100, 79, 117, 116, 18, 45, 46, 101, 105, 103, 114, 46, 102, 117, + 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 97, 99, + 116, 105, 111, 110, 46, 65, 99, 116, 105, 111, 110, 67, 111, 109, 109, 97, 110, 100, 26, + 46, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, + 111, 116, 111, 99, 111, 108, 46, 97, 99, 116, 105, 111, 110, 46, 65, 99, 116, 105, 111, + 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 3, 136, 2, 0, 40, 0, 48, 1, 18, 120, 10, + 14, 104, 97, 110, 100, 108, 101, 83, 116, 114, 101, 97, 109, 101, 100, 18, 45, 46, 101, + 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, + 111, 99, 111, 108, 46, 97, 99, 116, 105, 111, 110, 46, 65, 99, 116, 105, 111, 110, 67, + 111, 109, 109, 97, 110, 100, 26, 46, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, + 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 97, 99, 116, 105, 111, + 110, 46, 65, 99, 116, 105, 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 34, 3, 136, 2, + 0, 40, 1, 48, 1>> + ) + end + + rpc :handleUnary, + Eigr.Functions.Protocol.Action.ActionCommand, + Eigr.Functions.Protocol.Action.ActionResponse + + rpc :handleStreamedIn, + stream(Eigr.Functions.Protocol.Action.ActionCommand), + Eigr.Functions.Protocol.Action.ActionResponse + + rpc :handleStreamedOut, + Eigr.Functions.Protocol.Action.ActionCommand, + stream(Eigr.Functions.Protocol.Action.ActionResponse) + + rpc :handleStreamed, + stream(Eigr.Functions.Protocol.Action.ActionCommand), + stream(Eigr.Functions.Protocol.Action.ActionResponse) +end + +defmodule Eigr.Functions.Protocol.Action.ActionProtocol.Stub do + @moduledoc false + use GRPC.Stub, service: Eigr.Functions.Protocol.Action.ActionProtocol.Service +end diff --git a/apps/eigr_protocol/lib/eigr/functions/protocol/entity.pb.ex b/apps/eigr_protocol/lib/eigr/functions/protocol/entity.pb.ex new file mode 100644 index 0000000..fc762f3 --- /dev/null +++ b/apps/eigr_protocol/lib/eigr/functions/protocol/entity.pb.ex @@ -0,0 +1,537 @@ +defmodule Eigr.Functions.Protocol.Metadata do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + entries: [Eigr.Functions.Protocol.MetadataEntry.t()] + } + defstruct [:entries] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 8, 77, 101, 116, 97, 100, 97, 116, 97, 18, 64, 10, 7, 101, 110, 116, 114, 105, 101, + 115, 24, 1, 32, 3, 40, 11, 50, 38, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, + 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 77, 101, 116, 97, 100, + 97, 116, 97, 69, 110, 116, 114, 121, 82, 7, 101, 110, 116, 114, 105, 101, 115>> + ) + end + + field :entries, 1, repeated: true, type: Eigr.Functions.Protocol.MetadataEntry +end + +defmodule Eigr.Functions.Protocol.MetadataEntry do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + value: {atom, any}, + key: String.t() + } + defstruct [:value, :key] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 13, 77, 101, 116, 97, 100, 97, 116, 97, 69, 110, 116, 114, 121, 18, 16, 10, 3, 107, + 101, 121, 24, 1, 32, 1, 40, 9, 82, 3, 107, 101, 121, 18, 35, 10, 12, 115, 116, 114, 105, + 110, 103, 95, 118, 97, 108, 117, 101, 24, 2, 32, 1, 40, 9, 72, 0, 82, 11, 115, 116, 114, + 105, 110, 103, 86, 97, 108, 117, 101, 18, 33, 10, 11, 98, 121, 116, 101, 115, 95, 118, 97, + 108, 117, 101, 24, 3, 32, 1, 40, 12, 72, 0, 82, 10, 98, 121, 116, 101, 115, 86, 97, 108, + 117, 101, 66, 7, 10, 5, 118, 97, 108, 117, 101>> + ) + end + + oneof :value, 0 + field :key, 1, type: :string + field :string_value, 2, type: :string, oneof: 0 + field :bytes_value, 3, type: :bytes, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.Reply do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + payload: Google.Protobuf.Any.t() | nil, + metadata: Eigr.Functions.Protocol.Metadata.t() | nil + } + defstruct [:payload, :metadata] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 5, 82, 101, 112, 108, 121, 18, 46, 10, 7, 112, 97, 121, 108, 111, 97, 100, 24, 1, 32, + 1, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, + 102, 46, 65, 110, 121, 82, 7, 112, 97, 121, 108, 111, 97, 100, 18, 61, 10, 8, 109, 101, + 116, 97, 100, 97, 116, 97, 24, 2, 32, 1, 40, 11, 50, 33, 46, 101, 105, 103, 114, 46, 102, + 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 77, + 101, 116, 97, 100, 97, 116, 97, 82, 8, 109, 101, 116, 97, 100, 97, 116, 97>> + ) + end + + field :payload, 1, type: Google.Protobuf.Any + field :metadata, 2, type: Eigr.Functions.Protocol.Metadata +end + +defmodule Eigr.Functions.Protocol.Forward do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + service_name: String.t(), + command_name: String.t(), + payload: Google.Protobuf.Any.t() | nil, + metadata: Eigr.Functions.Protocol.Metadata.t() | nil + } + defstruct [:service_name, :command_name, :payload, :metadata] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 7, 70, 111, 114, 119, 97, 114, 100, 18, 33, 10, 12, 115, 101, 114, 118, 105, 99, 101, + 95, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 11, 115, 101, 114, 118, 105, 99, 101, 78, + 97, 109, 101, 18, 33, 10, 12, 99, 111, 109, 109, 97, 110, 100, 95, 110, 97, 109, 101, 24, + 2, 32, 1, 40, 9, 82, 11, 99, 111, 109, 109, 97, 110, 100, 78, 97, 109, 101, 18, 46, 10, 7, + 112, 97, 121, 108, 111, 97, 100, 24, 3, 32, 1, 40, 11, 50, 20, 46, 103, 111, 111, 103, + 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 65, 110, 121, 82, 7, 112, 97, + 121, 108, 111, 97, 100, 18, 61, 10, 8, 109, 101, 116, 97, 100, 97, 116, 97, 24, 4, 32, 1, + 40, 11, 50, 33, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, + 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 77, 101, 116, 97, 100, 97, 116, 97, 82, 8, + 109, 101, 116, 97, 100, 97, 116, 97>> + ) + end + + field :service_name, 1, type: :string + field :command_name, 2, type: :string + field :payload, 3, type: Google.Protobuf.Any + field :metadata, 4, type: Eigr.Functions.Protocol.Metadata +end + +defmodule Eigr.Functions.Protocol.ClientAction do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + action: {atom, any} + } + defstruct [:action] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 12, 67, 108, 105, 101, 110, 116, 65, 99, 116, 105, 111, 110, 18, 54, 10, 5, 114, 101, + 112, 108, 121, 24, 1, 32, 1, 40, 11, 50, 30, 46, 101, 105, 103, 114, 46, 102, 117, 110, + 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 82, 101, 112, + 108, 121, 72, 0, 82, 5, 114, 101, 112, 108, 121, 18, 60, 10, 7, 102, 111, 114, 119, 97, + 114, 100, 24, 2, 32, 1, 40, 11, 50, 32, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, + 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 70, 111, 114, 119, + 97, 114, 100, 72, 0, 82, 7, 102, 111, 114, 119, 97, 114, 100, 18, 60, 10, 7, 102, 97, 105, + 108, 117, 114, 101, 24, 3, 32, 1, 40, 11, 50, 32, 46, 101, 105, 103, 114, 46, 102, 117, + 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 70, 97, + 105, 108, 117, 114, 101, 72, 0, 82, 7, 102, 97, 105, 108, 117, 114, 101, 66, 8, 10, 6, 97, + 99, 116, 105, 111, 110>> + ) + end + + oneof :action, 0 + field :reply, 1, type: Eigr.Functions.Protocol.Reply, oneof: 0 + field :forward, 2, type: Eigr.Functions.Protocol.Forward, oneof: 0 + field :failure, 3, type: Eigr.Functions.Protocol.Failure, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.SideEffect do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + service_name: String.t(), + command_name: String.t(), + payload: Google.Protobuf.Any.t() | nil, + synchronous: boolean, + broadcast: boolean, + metadata: Eigr.Functions.Protocol.Metadata.t() | nil + } + defstruct [:service_name, :command_name, :payload, :synchronous, :broadcast, :metadata] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 10, 83, 105, 100, 101, 69, 102, 102, 101, 99, 116, 18, 33, 10, 12, 115, 101, 114, 118, + 105, 99, 101, 95, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 11, 115, 101, 114, 118, 105, + 99, 101, 78, 97, 109, 101, 18, 33, 10, 12, 99, 111, 109, 109, 97, 110, 100, 95, 110, 97, + 109, 101, 24, 2, 32, 1, 40, 9, 82, 11, 99, 111, 109, 109, 97, 110, 100, 78, 97, 109, 101, + 18, 46, 10, 7, 112, 97, 121, 108, 111, 97, 100, 24, 3, 32, 1, 40, 11, 50, 20, 46, 103, + 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 65, 110, 121, 82, + 7, 112, 97, 121, 108, 111, 97, 100, 18, 32, 10, 11, 115, 121, 110, 99, 104, 114, 111, 110, + 111, 117, 115, 24, 4, 32, 1, 40, 8, 82, 11, 115, 121, 110, 99, 104, 114, 111, 110, 111, + 117, 115, 18, 28, 10, 9, 98, 114, 111, 97, 100, 99, 97, 115, 116, 24, 6, 32, 1, 40, 8, 82, + 9, 98, 114, 111, 97, 100, 99, 97, 115, 116, 18, 61, 10, 8, 109, 101, 116, 97, 100, 97, + 116, 97, 24, 5, 32, 1, 40, 11, 50, 33, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, + 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 77, 101, 116, 97, 100, + 97, 116, 97, 82, 8, 109, 101, 116, 97, 100, 97, 116, 97>> + ) + end + + field :service_name, 1, type: :string + field :command_name, 2, type: :string + field :payload, 3, type: Google.Protobuf.Any + field :synchronous, 4, type: :bool + field :broadcast, 6, type: :bool + field :metadata, 5, type: Eigr.Functions.Protocol.Metadata +end + +defmodule Eigr.Functions.Protocol.Command do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + entity_id: String.t(), + id: integer, + name: String.t(), + payload: Google.Protobuf.Any.t() | nil, + streamed: boolean, + metadata: Eigr.Functions.Protocol.Metadata.t() | nil + } + defstruct [:entity_id, :id, :name, :payload, :streamed, :metadata] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 7, 67, 111, 109, 109, 97, 110, 100, 18, 27, 10, 9, 101, 110, 116, 105, 116, 121, 95, + 105, 100, 24, 1, 32, 1, 40, 9, 82, 8, 101, 110, 116, 105, 116, 121, 73, 100, 18, 14, 10, + 2, 105, 100, 24, 2, 32, 1, 40, 3, 82, 2, 105, 100, 18, 18, 10, 4, 110, 97, 109, 101, 24, + 3, 32, 1, 40, 9, 82, 4, 110, 97, 109, 101, 18, 46, 10, 7, 112, 97, 121, 108, 111, 97, 100, + 24, 4, 32, 1, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, + 111, 98, 117, 102, 46, 65, 110, 121, 82, 7, 112, 97, 121, 108, 111, 97, 100, 18, 26, 10, + 8, 115, 116, 114, 101, 97, 109, 101, 100, 24, 5, 32, 1, 40, 8, 82, 8, 115, 116, 114, 101, + 97, 109, 101, 100, 18, 61, 10, 8, 109, 101, 116, 97, 100, 97, 116, 97, 24, 6, 32, 1, 40, + 11, 50, 33, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, + 112, 114, 111, 116, 111, 99, 111, 108, 46, 77, 101, 116, 97, 100, 97, 116, 97, 82, 8, 109, + 101, 116, 97, 100, 97, 116, 97>> + ) + end + + field :entity_id, 1, type: :string + field :id, 2, type: :int64 + field :name, 3, type: :string + field :payload, 4, type: Google.Protobuf.Any + field :streamed, 5, type: :bool + field :metadata, 6, type: Eigr.Functions.Protocol.Metadata +end + +defmodule Eigr.Functions.Protocol.StreamCancelled do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + entity_id: String.t(), + id: integer + } + defstruct [:entity_id, :id] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 15, 83, 116, 114, 101, 97, 109, 67, 97, 110, 99, 101, 108, 108, 101, 100, 18, 27, 10, + 9, 101, 110, 116, 105, 116, 121, 95, 105, 100, 24, 1, 32, 1, 40, 9, 82, 8, 101, 110, 116, + 105, 116, 121, 73, 100, 18, 14, 10, 2, 105, 100, 24, 2, 32, 1, 40, 3, 82, 2, 105, 100>> + ) + end + + field :entity_id, 1, type: :string + field :id, 2, type: :int64 +end + +defmodule Eigr.Functions.Protocol.Failure do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + command_id: integer, + description: String.t(), + restart: boolean + } + defstruct [:command_id, :description, :restart] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 7, 70, 97, 105, 108, 117, 114, 101, 18, 29, 10, 10, 99, 111, 109, 109, 97, 110, 100, + 95, 105, 100, 24, 1, 32, 1, 40, 3, 82, 9, 99, 111, 109, 109, 97, 110, 100, 73, 100, 18, + 32, 10, 11, 100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 24, 2, 32, 1, 40, 9, 82, + 11, 100, 101, 115, 99, 114, 105, 112, 116, 105, 111, 110, 18, 24, 10, 7, 114, 101, 115, + 116, 97, 114, 116, 24, 3, 32, 1, 40, 8, 82, 7, 114, 101, 115, 116, 97, 114, 116>> + ) + end + + field :command_id, 1, type: :int64 + field :description, 2, type: :string + field :restart, 3, type: :bool +end + +defmodule Eigr.Functions.Protocol.EntitySpec do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + proto: binary, + entities: [Eigr.Functions.Protocol.Entity.t()], + service_info: Eigr.Functions.Protocol.ServiceInfo.t() | nil + } + defstruct [:proto, :entities, :service_info] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 10, 69, 110, 116, 105, 116, 121, 83, 112, 101, 99, 18, 20, 10, 5, 112, 114, 111, 116, + 111, 24, 1, 32, 1, 40, 12, 82, 5, 112, 114, 111, 116, 111, 18, 59, 10, 8, 101, 110, 116, + 105, 116, 105, 101, 115, 24, 2, 32, 3, 40, 11, 50, 31, 46, 101, 105, 103, 114, 46, 102, + 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 69, + 110, 116, 105, 116, 121, 82, 8, 101, 110, 116, 105, 116, 105, 101, 115, 18, 71, 10, 12, + 115, 101, 114, 118, 105, 99, 101, 95, 105, 110, 102, 111, 24, 3, 32, 1, 40, 11, 50, 36, + 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, + 116, 111, 99, 111, 108, 46, 83, 101, 114, 118, 105, 99, 101, 73, 110, 102, 111, 82, 11, + 115, 101, 114, 118, 105, 99, 101, 73, 110, 102, 111>> + ) + end + + field :proto, 1, type: :bytes + field :entities, 2, repeated: true, type: Eigr.Functions.Protocol.Entity + field :service_info, 3, type: Eigr.Functions.Protocol.ServiceInfo +end + +defmodule Eigr.Functions.Protocol.ServiceInfo do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + service_name: String.t(), + service_version: String.t(), + service_runtime: String.t(), + support_library_name: String.t(), + support_library_version: String.t(), + protocol_major_version: integer, + protocol_minor_version: integer + } + defstruct [ + :service_name, + :service_version, + :service_runtime, + :support_library_name, + :support_library_version, + :protocol_major_version, + :protocol_minor_version + ] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 11, 83, 101, 114, 118, 105, 99, 101, 73, 110, 102, 111, 18, 33, 10, 12, 115, 101, 114, + 118, 105, 99, 101, 95, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 11, 115, 101, 114, 118, + 105, 99, 101, 78, 97, 109, 101, 18, 39, 10, 15, 115, 101, 114, 118, 105, 99, 101, 95, 118, + 101, 114, 115, 105, 111, 110, 24, 2, 32, 1, 40, 9, 82, 14, 115, 101, 114, 118, 105, 99, + 101, 86, 101, 114, 115, 105, 111, 110, 18, 39, 10, 15, 115, 101, 114, 118, 105, 99, 101, + 95, 114, 117, 110, 116, 105, 109, 101, 24, 3, 32, 1, 40, 9, 82, 14, 115, 101, 114, 118, + 105, 99, 101, 82, 117, 110, 116, 105, 109, 101, 18, 48, 10, 20, 115, 117, 112, 112, 111, + 114, 116, 95, 108, 105, 98, 114, 97, 114, 121, 95, 110, 97, 109, 101, 24, 4, 32, 1, 40, 9, + 82, 18, 115, 117, 112, 112, 111, 114, 116, 76, 105, 98, 114, 97, 114, 121, 78, 97, 109, + 101, 18, 54, 10, 23, 115, 117, 112, 112, 111, 114, 116, 95, 108, 105, 98, 114, 97, 114, + 121, 95, 118, 101, 114, 115, 105, 111, 110, 24, 5, 32, 1, 40, 9, 82, 21, 115, 117, 112, + 112, 111, 114, 116, 76, 105, 98, 114, 97, 114, 121, 86, 101, 114, 115, 105, 111, 110, 18, + 52, 10, 22, 112, 114, 111, 116, 111, 99, 111, 108, 95, 109, 97, 106, 111, 114, 95, 118, + 101, 114, 115, 105, 111, 110, 24, 6, 32, 1, 40, 5, 82, 20, 112, 114, 111, 116, 111, 99, + 111, 108, 77, 97, 106, 111, 114, 86, 101, 114, 115, 105, 111, 110, 18, 52, 10, 22, 112, + 114, 111, 116, 111, 99, 111, 108, 95, 109, 105, 110, 111, 114, 95, 118, 101, 114, 115, + 105, 111, 110, 24, 7, 32, 1, 40, 5, 82, 20, 112, 114, 111, 116, 111, 99, 111, 108, 77, + 105, 110, 111, 114, 86, 101, 114, 115, 105, 111, 110>> + ) + end + + field :service_name, 1, type: :string + field :service_version, 2, type: :string + field :service_runtime, 3, type: :string + field :support_library_name, 4, type: :string + field :support_library_version, 5, type: :string + field :protocol_major_version, 6, type: :int32 + field :protocol_minor_version, 7, type: :int32 +end + +defmodule Eigr.Functions.Protocol.Entity do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + entity_type: String.t(), + service_name: String.t(), + persistence_id: String.t(), + passivation_strategy: Eigr.Functions.Protocol.EntityPassivationStrategy.t() | nil + } + defstruct [:entity_type, :service_name, :persistence_id, :passivation_strategy] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 6, 69, 110, 116, 105, 116, 121, 18, 31, 10, 11, 101, 110, 116, 105, 116, 121, 95, 116, + 121, 112, 101, 24, 1, 32, 1, 40, 9, 82, 10, 101, 110, 116, 105, 116, 121, 84, 121, 112, + 101, 18, 33, 10, 12, 115, 101, 114, 118, 105, 99, 101, 95, 110, 97, 109, 101, 24, 2, 32, + 1, 40, 9, 82, 11, 115, 101, 114, 118, 105, 99, 101, 78, 97, 109, 101, 18, 37, 10, 14, 112, + 101, 114, 115, 105, 115, 116, 101, 110, 99, 101, 95, 105, 100, 24, 3, 32, 1, 40, 9, 82, + 13, 112, 101, 114, 115, 105, 115, 116, 101, 110, 99, 101, 73, 100, 18, 101, 10, 20, 112, + 97, 115, 115, 105, 118, 97, 116, 105, 111, 110, 95, 115, 116, 114, 97, 116, 101, 103, 121, + 24, 4, 32, 1, 40, 11, 50, 50, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, + 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 69, 110, 116, 105, 116, 121, + 80, 97, 115, 115, 105, 118, 97, 116, 105, 111, 110, 83, 116, 114, 97, 116, 101, 103, 121, + 82, 19, 112, 97, 115, 115, 105, 118, 97, 116, 105, 111, 110, 83, 116, 114, 97, 116, 101, + 103, 121>> + ) + end + + field :entity_type, 1, type: :string + field :service_name, 2, type: :string + field :persistence_id, 3, type: :string + field :passivation_strategy, 4, type: Eigr.Functions.Protocol.EntityPassivationStrategy +end + +defmodule Eigr.Functions.Protocol.EntityPassivationStrategy do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + strategy: {atom, any} + } + defstruct [:strategy] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 25, 69, 110, 116, 105, 116, 121, 80, 97, 115, 115, 105, 118, 97, 116, 105, 111, 110, + 83, 116, 114, 97, 116, 101, 103, 121, 18, 79, 10, 7, 116, 105, 109, 101, 111, 117, 116, + 24, 1, 32, 1, 40, 11, 50, 51, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, + 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 84, 105, 109, 101, 111, 117, + 116, 80, 97, 115, 115, 105, 118, 97, 116, 105, 111, 110, 83, 116, 114, 97, 116, 101, 103, + 121, 72, 0, 82, 7, 116, 105, 109, 101, 111, 117, 116, 66, 10, 10, 8, 115, 116, 114, 97, + 116, 101, 103, 121>> + ) + end + + oneof :strategy, 0 + field :timeout, 1, type: Eigr.Functions.Protocol.TimeoutPassivationStrategy, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.TimeoutPassivationStrategy do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + timeout: integer + } + defstruct [:timeout] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 26, 84, 105, 109, 101, 111, 117, 116, 80, 97, 115, 115, 105, 118, 97, 116, 105, 111, + 110, 83, 116, 114, 97, 116, 101, 103, 121, 18, 24, 10, 7, 116, 105, 109, 101, 111, 117, + 116, 24, 1, 32, 1, 40, 3, 82, 7, 116, 105, 109, 101, 111, 117, 116>> + ) + end + + field :timeout, 1, type: :int64 +end + +defmodule Eigr.Functions.Protocol.UserFunctionError do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + message: String.t() + } + defstruct [:message] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 85, 115, 101, 114, 70, 117, 110, 99, 116, 105, 111, 110, 69, 114, 114, 111, 114, + 18, 24, 10, 7, 109, 101, 115, 115, 97, 103, 101, 24, 1, 32, 1, 40, 9, 82, 7, 109, 101, + 115, 115, 97, 103, 101>> + ) + end + + field :message, 1, type: :string +end + +defmodule Eigr.Functions.Protocol.ProxyInfo do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + protocol_major_version: integer, + protocol_minor_version: integer, + proxy_name: String.t(), + proxy_version: String.t(), + supported_entity_types: [String.t()] + } + defstruct [ + :protocol_major_version, + :protocol_minor_version, + :proxy_name, + :proxy_version, + :supported_entity_types + ] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 9, 80, 114, 111, 120, 121, 73, 110, 102, 111, 18, 52, 10, 22, 112, 114, 111, 116, 111, + 99, 111, 108, 95, 109, 97, 106, 111, 114, 95, 118, 101, 114, 115, 105, 111, 110, 24, 1, + 32, 1, 40, 5, 82, 20, 112, 114, 111, 116, 111, 99, 111, 108, 77, 97, 106, 111, 114, 86, + 101, 114, 115, 105, 111, 110, 18, 52, 10, 22, 112, 114, 111, 116, 111, 99, 111, 108, 95, + 109, 105, 110, 111, 114, 95, 118, 101, 114, 115, 105, 111, 110, 24, 2, 32, 1, 40, 5, 82, + 20, 112, 114, 111, 116, 111, 99, 111, 108, 77, 105, 110, 111, 114, 86, 101, 114, 115, 105, + 111, 110, 18, 29, 10, 10, 112, 114, 111, 120, 121, 95, 110, 97, 109, 101, 24, 3, 32, 1, + 40, 9, 82, 9, 112, 114, 111, 120, 121, 78, 97, 109, 101, 18, 35, 10, 13, 112, 114, 111, + 120, 121, 95, 118, 101, 114, 115, 105, 111, 110, 24, 4, 32, 1, 40, 9, 82, 12, 112, 114, + 111, 120, 121, 86, 101, 114, 115, 105, 111, 110, 18, 52, 10, 22, 115, 117, 112, 112, 111, + 114, 116, 101, 100, 95, 101, 110, 116, 105, 116, 121, 95, 116, 121, 112, 101, 115, 24, 5, + 32, 3, 40, 9, 82, 20, 115, 117, 112, 112, 111, 114, 116, 101, 100, 69, 110, 116, 105, 116, + 121, 84, 121, 112, 101, 115>> + ) + end + + field :protocol_major_version, 1, type: :int32 + field :protocol_minor_version, 2, type: :int32 + field :proxy_name, 3, type: :string + field :proxy_version, 4, type: :string + field :supported_entity_types, 5, repeated: true, type: :string +end + +defmodule Eigr.Functions.Protocol.EntityDiscovery.Service do + @moduledoc false + use GRPC.Service, name: "eigr.functions.protocol.EntityDiscovery" + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.ServiceDescriptorProto.decode( + <<10, 15, 69, 110, 116, 105, 116, 121, 68, 105, 115, 99, 111, 118, 101, 114, 121, 18, 92, + 10, 8, 100, 105, 115, 99, 111, 118, 101, 114, 18, 34, 46, 101, 105, 103, 114, 46, 102, + 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 80, + 114, 111, 120, 121, 73, 110, 102, 111, 26, 35, 46, 101, 105, 103, 114, 46, 102, 117, 110, + 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 69, 110, 116, + 105, 116, 121, 83, 112, 101, 99, 34, 3, 136, 2, 0, 40, 0, 48, 0, 18, 90, 10, 11, 114, 101, + 112, 111, 114, 116, 69, 114, 114, 111, 114, 18, 42, 46, 101, 105, 103, 114, 46, 102, 117, + 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 85, 115, + 101, 114, 70, 117, 110, 99, 116, 105, 111, 110, 69, 114, 114, 111, 114, 26, 22, 46, 103, + 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 69, 109, 112, 116, + 121, 34, 3, 136, 2, 0, 40, 0, 48, 0>> + ) + end + + rpc :discover, Eigr.Functions.Protocol.ProxyInfo, Eigr.Functions.Protocol.EntitySpec + rpc :reportError, Eigr.Functions.Protocol.UserFunctionError, Google.Protobuf.Empty +end + +defmodule Eigr.Functions.Protocol.EntityDiscovery.Stub do + @moduledoc false + use GRPC.Stub, service: Eigr.Functions.Protocol.EntityDiscovery.Service +end diff --git a/apps/eigr_protocol/lib/eigr/functions/protocol/entity_key.pb.ex b/apps/eigr_protocol/lib/eigr/functions/protocol/entity_key.pb.ex new file mode 100644 index 0000000..e69de29 diff --git a/apps/eigr_protocol/lib/eigr/functions/protocol/event_sourced.pb.ex b/apps/eigr_protocol/lib/eigr/functions/protocol/event_sourced.pb.ex new file mode 100644 index 0000000..16b5636 --- /dev/null +++ b/apps/eigr_protocol/lib/eigr/functions/protocol/event_sourced.pb.ex @@ -0,0 +1,216 @@ +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourcedInit do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + service_name: String.t(), + entity_id: String.t(), + snapshot: Eigr.Functions.Protocol.Eventsourced.EventSourcedSnapshot.t() | nil + } + defstruct [:service_name, :entity_id, :snapshot] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 16, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 73, 110, 105, 116, 18, + 33, 10, 12, 115, 101, 114, 118, 105, 99, 101, 95, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, + 82, 11, 115, 101, 114, 118, 105, 99, 101, 78, 97, 109, 101, 18, 27, 10, 9, 101, 110, 116, + 105, 116, 121, 95, 105, 100, 24, 2, 32, 1, 40, 9, 82, 8, 101, 110, 116, 105, 116, 121, 73, + 100, 18, 86, 10, 8, 115, 110, 97, 112, 115, 104, 111, 116, 24, 3, 32, 1, 40, 11, 50, 58, + 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, + 116, 111, 99, 111, 108, 46, 101, 118, 101, 110, 116, 115, 111, 117, 114, 99, 101, 100, 46, + 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 83, 110, 97, 112, 115, 104, 111, + 116, 82, 8, 115, 110, 97, 112, 115, 104, 111, 116>> + ) + end + + field :service_name, 1, type: :string + field :entity_id, 2, type: :string + field :snapshot, 3, type: Eigr.Functions.Protocol.Eventsourced.EventSourcedSnapshot +end + +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourcedSnapshot do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + snapshot_sequence: integer, + snapshot: Google.Protobuf.Any.t() | nil + } + defstruct [:snapshot_sequence, :snapshot] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 20, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 83, 110, 97, 112, 115, + 104, 111, 116, 18, 43, 10, 17, 115, 110, 97, 112, 115, 104, 111, 116, 95, 115, 101, 113, + 117, 101, 110, 99, 101, 24, 1, 32, 1, 40, 3, 82, 16, 115, 110, 97, 112, 115, 104, 111, + 116, 83, 101, 113, 117, 101, 110, 99, 101, 18, 48, 10, 8, 115, 110, 97, 112, 115, 104, + 111, 116, 24, 2, 32, 1, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, + 111, 116, 111, 98, 117, 102, 46, 65, 110, 121, 82, 8, 115, 110, 97, 112, 115, 104, 111, + 116>> + ) + end + + field :snapshot_sequence, 1, type: :int64 + field :snapshot, 2, type: Google.Protobuf.Any +end + +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourcedEvent do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + sequence: integer, + payload: Google.Protobuf.Any.t() | nil + } + defstruct [:sequence, :payload] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 69, 118, 101, 110, 116, + 18, 26, 10, 8, 115, 101, 113, 117, 101, 110, 99, 101, 24, 1, 32, 1, 40, 3, 82, 8, 115, + 101, 113, 117, 101, 110, 99, 101, 18, 46, 10, 7, 112, 97, 121, 108, 111, 97, 100, 24, 2, + 32, 1, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, + 117, 102, 46, 65, 110, 121, 82, 7, 112, 97, 121, 108, 111, 97, 100>> + ) + end + + field :sequence, 1, type: :int64 + field :payload, 2, type: Google.Protobuf.Any +end + +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourcedReply do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + command_id: integer, + client_action: Eigr.Functions.Protocol.ClientAction.t() | nil, + side_effects: [Eigr.Functions.Protocol.SideEffect.t()], + events: [Google.Protobuf.Any.t()], + snapshot: Google.Protobuf.Any.t() | nil + } + defstruct [:command_id, :client_action, :side_effects, :events, :snapshot] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 82, 101, 112, 108, 121, + 18, 29, 10, 10, 99, 111, 109, 109, 97, 110, 100, 95, 105, 100, 24, 1, 32, 1, 40, 3, 82, 9, + 99, 111, 109, 109, 97, 110, 100, 73, 100, 18, 74, 10, 13, 99, 108, 105, 101, 110, 116, 95, + 97, 99, 116, 105, 111, 110, 24, 2, 32, 1, 40, 11, 50, 37, 46, 101, 105, 103, 114, 46, 102, + 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 67, + 108, 105, 101, 110, 116, 65, 99, 116, 105, 111, 110, 82, 12, 99, 108, 105, 101, 110, 116, + 65, 99, 116, 105, 111, 110, 18, 70, 10, 12, 115, 105, 100, 101, 95, 101, 102, 102, 101, + 99, 116, 115, 24, 3, 32, 3, 40, 11, 50, 35, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, + 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 83, 105, 100, 101, + 69, 102, 102, 101, 99, 116, 82, 11, 115, 105, 100, 101, 69, 102, 102, 101, 99, 116, 115, + 18, 44, 10, 6, 101, 118, 101, 110, 116, 115, 24, 4, 32, 3, 40, 11, 50, 20, 46, 103, 111, + 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 65, 110, 121, 82, 6, + 101, 118, 101, 110, 116, 115, 18, 48, 10, 8, 115, 110, 97, 112, 115, 104, 111, 116, 24, 5, + 32, 1, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, + 117, 102, 46, 65, 110, 121, 82, 8, 115, 110, 97, 112, 115, 104, 111, 116>> + ) + end + + field :command_id, 1, type: :int64 + field :client_action, 2, type: Eigr.Functions.Protocol.ClientAction + field :side_effects, 3, repeated: true, type: Eigr.Functions.Protocol.SideEffect + field :events, 4, repeated: true, type: Google.Protobuf.Any + field :snapshot, 5, type: Google.Protobuf.Any +end + +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourcedStreamIn do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + message: {atom, any} + } + defstruct [:message] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 20, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 83, 116, 114, 101, 97, + 109, 73, 110, 18, 76, 10, 4, 105, 110, 105, 116, 24, 1, 32, 1, 40, 11, 50, 54, 46, 101, + 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, + 111, 99, 111, 108, 46, 101, 118, 101, 110, 116, 115, 111, 117, 114, 99, 101, 100, 46, 69, + 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 73, 110, 105, 116, 72, 0, 82, 4, 105, + 110, 105, 116, 18, 79, 10, 5, 101, 118, 101, 110, 116, 24, 2, 32, 1, 40, 11, 50, 55, 46, + 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, + 116, 111, 99, 111, 108, 46, 101, 118, 101, 110, 116, 115, 111, 117, 114, 99, 101, 100, 46, + 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 69, 118, 101, 110, 116, 72, 0, + 82, 5, 101, 118, 101, 110, 116, 18, 60, 10, 7, 99, 111, 109, 109, 97, 110, 100, 24, 3, 32, + 1, 40, 11, 50, 32, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, + 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 67, 111, 109, 109, 97, 110, 100, 72, 0, 82, + 7, 99, 111, 109, 109, 97, 110, 100, 66, 9, 10, 7, 109, 101, 115, 115, 97, 103, 101>> + ) + end + + oneof :message, 0 + field :init, 1, type: Eigr.Functions.Protocol.Eventsourced.EventSourcedInit, oneof: 0 + field :event, 2, type: Eigr.Functions.Protocol.Eventsourced.EventSourcedEvent, oneof: 0 + field :command, 3, type: Eigr.Functions.Protocol.Command, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourcedStreamOut do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + message: {atom, any} + } + defstruct [:message] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 21, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 83, 116, 114, 101, 97, + 109, 79, 117, 116, 18, 79, 10, 5, 114, 101, 112, 108, 121, 24, 1, 32, 1, 40, 11, 50, 55, + 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, + 116, 111, 99, 111, 108, 46, 101, 118, 101, 110, 116, 115, 111, 117, 114, 99, 101, 100, 46, + 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 82, 101, 112, 108, 121, 72, 0, + 82, 5, 114, 101, 112, 108, 121, 18, 60, 10, 7, 102, 97, 105, 108, 117, 114, 101, 24, 2, + 32, 1, 40, 11, 50, 32, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, + 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 70, 97, 105, 108, 117, 114, 101, 72, + 0, 82, 7, 102, 97, 105, 108, 117, 114, 101, 66, 9, 10, 7, 109, 101, 115, 115, 97, 103, + 101>> + ) + end + + oneof :message, 0 + field :reply, 1, type: Eigr.Functions.Protocol.Eventsourced.EventSourcedReply, oneof: 0 + field :failure, 2, type: Eigr.Functions.Protocol.Failure, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourced.Service do + @moduledoc false + use GRPC.Service, name: "eigr.functions.protocol.eventsourced.EventSourced" + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.ServiceDescriptorProto.decode( + <<10, 12, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 100, 18, 138, 1, 10, 6, 104, + 97, 110, 100, 108, 101, 18, 58, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, + 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 101, 118, 101, 110, 116, + 115, 111, 117, 114, 99, 101, 100, 46, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, + 100, 83, 116, 114, 101, 97, 109, 73, 110, 26, 59, 46, 101, 105, 103, 114, 46, 102, 117, + 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 101, 118, + 101, 110, 116, 115, 111, 117, 114, 99, 101, 100, 46, 69, 118, 101, 110, 116, 83, 111, 117, + 114, 99, 101, 100, 83, 116, 114, 101, 97, 109, 79, 117, 116, 34, 3, 136, 2, 0, 40, 1, 48, + 1>> + ) + end + + rpc :handle, + stream(Eigr.Functions.Protocol.Eventsourced.EventSourcedStreamIn), + stream(Eigr.Functions.Protocol.Eventsourced.EventSourcedStreamOut) +end + +defmodule Eigr.Functions.Protocol.Eventsourced.EventSourced.Stub do + @moduledoc false + use GRPC.Stub, service: Eigr.Functions.Protocol.Eventsourced.EventSourced.Service +end diff --git a/apps/eigr_protocol/lib/eigr/functions/protocol/eventing.pb.ex b/apps/eigr_protocol/lib/eigr/functions/protocol/eventing.pb.ex new file mode 100644 index 0000000..1aaf1a9 --- /dev/null +++ b/apps/eigr_protocol/lib/eigr/functions/protocol/eventing.pb.ex @@ -0,0 +1,77 @@ +defmodule Eigr.Functions.Protocol.Eventing.Eventing do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + in: Eigr.Functions.Protocol.Eventing.EventSource.t() | nil, + out: Eigr.Functions.Protocol.Eventing.EventDestination.t() | nil + } + defstruct [:in, :out] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 8, 69, 118, 101, 110, 116, 105, 110, 103, 18, 61, 10, 2, 105, 110, 24, 1, 32, 1, 40, + 11, 50, 45, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, + 112, 114, 111, 116, 111, 99, 111, 108, 46, 101, 118, 101, 110, 116, 105, 110, 103, 46, 69, + 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 82, 2, 105, 110, 18, 68, 10, 3, 111, 117, + 116, 24, 2, 32, 1, 40, 11, 50, 50, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, + 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 101, 118, 101, 110, + 116, 105, 110, 103, 46, 69, 118, 101, 110, 116, 68, 101, 115, 116, 105, 110, 97, 116, 105, + 111, 110, 82, 3, 111, 117, 116>> + ) + end + + field :in, 1, type: Eigr.Functions.Protocol.Eventing.EventSource + field :out, 2, type: Eigr.Functions.Protocol.Eventing.EventDestination +end + +defmodule Eigr.Functions.Protocol.Eventing.EventSource do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + source: {atom, any}, + consumer_group: String.t() + } + defstruct [:source, :consumer_group] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 11, 69, 118, 101, 110, 116, 83, 111, 117, 114, 99, 101, 18, 37, 10, 14, 99, 111, 110, + 115, 117, 109, 101, 114, 95, 103, 114, 111, 117, 112, 24, 1, 32, 1, 40, 9, 82, 13, 99, + 111, 110, 115, 117, 109, 101, 114, 71, 114, 111, 117, 112, 18, 22, 10, 5, 116, 111, 112, + 105, 99, 24, 2, 32, 1, 40, 9, 72, 0, 82, 5, 116, 111, 112, 105, 99, 18, 29, 10, 9, 101, + 118, 101, 110, 116, 95, 108, 111, 103, 24, 3, 32, 1, 40, 9, 72, 0, 82, 8, 101, 118, 101, + 110, 116, 76, 111, 103, 66, 8, 10, 6, 115, 111, 117, 114, 99, 101>> + ) + end + + oneof :source, 0 + field :consumer_group, 1, type: :string + field :topic, 2, type: :string, oneof: 0 + field :event_log, 3, type: :string, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.Eventing.EventDestination do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + destination: {atom, any} + } + defstruct [:destination] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 16, 69, 118, 101, 110, 116, 68, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110, 18, + 22, 10, 5, 116, 111, 112, 105, 99, 24, 1, 32, 1, 40, 9, 72, 0, 82, 5, 116, 111, 112, 105, + 99, 66, 13, 10, 11, 100, 101, 115, 116, 105, 110, 97, 116, 105, 111, 110>> + ) + end + + oneof :destination, 0 + field :topic, 1, type: :string, oneof: 0 +end diff --git a/apps/eigr_protocol/lib/eigr/functions/protocol/value_entity.pb.ex b/apps/eigr_protocol/lib/eigr/functions/protocol/value_entity.pb.ex new file mode 100644 index 0000000..3d2cf8c --- /dev/null +++ b/apps/eigr_protocol/lib/eigr/functions/protocol/value_entity.pb.ex @@ -0,0 +1,244 @@ +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityStreamIn do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + message: {atom, any} + } + defstruct [:message] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 19, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 83, 116, 114, 101, 97, 109, + 73, 110, 18, 74, 10, 4, 105, 110, 105, 116, 24, 1, 32, 1, 40, 11, 50, 52, 46, 101, 105, + 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, + 111, 108, 46, 118, 97, 108, 117, 101, 101, 110, 116, 105, 116, 121, 46, 86, 97, 108, 117, + 101, 69, 110, 116, 105, 116, 121, 73, 110, 105, 116, 72, 0, 82, 4, 105, 110, 105, 116, 18, + 60, 10, 7, 99, 111, 109, 109, 97, 110, 100, 24, 2, 32, 1, 40, 11, 50, 32, 46, 101, 105, + 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, + 111, 108, 46, 67, 111, 109, 109, 97, 110, 100, 72, 0, 82, 7, 99, 111, 109, 109, 97, 110, + 100, 66, 9, 10, 7, 109, 101, 115, 115, 97, 103, 101>> + ) + end + + oneof :message, 0 + field :init, 1, type: Eigr.Functions.Protocol.Valueentity.ValueEntityInit, oneof: 0 + field :command, 2, type: Eigr.Functions.Protocol.Command, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityInit do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + service_name: String.t(), + entity_id: String.t(), + state: Eigr.Functions.Protocol.Valueentity.ValueEntityInitState.t() | nil + } + defstruct [:service_name, :entity_id, :state] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 15, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 73, 110, 105, 116, 18, 33, 10, + 12, 115, 101, 114, 118, 105, 99, 101, 95, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 11, + 115, 101, 114, 118, 105, 99, 101, 78, 97, 109, 101, 18, 27, 10, 9, 101, 110, 116, 105, + 116, 121, 95, 105, 100, 24, 2, 32, 1, 40, 9, 82, 8, 101, 110, 116, 105, 116, 121, 73, 100, + 18, 79, 10, 5, 115, 116, 97, 116, 101, 24, 3, 32, 1, 40, 11, 50, 57, 46, 101, 105, 103, + 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, + 108, 46, 118, 97, 108, 117, 101, 101, 110, 116, 105, 116, 121, 46, 86, 97, 108, 117, 101, + 69, 110, 116, 105, 116, 121, 73, 110, 105, 116, 83, 116, 97, 116, 101, 82, 5, 115, 116, + 97, 116, 101>> + ) + end + + field :service_name, 1, type: :string + field :entity_id, 2, type: :string + field :state, 3, type: Eigr.Functions.Protocol.Valueentity.ValueEntityInitState +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityInitState do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + value: Google.Protobuf.Any.t() | nil + } + defstruct [:value] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 20, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 73, 110, 105, 116, 83, 116, + 97, 116, 101, 18, 42, 10, 5, 118, 97, 108, 117, 101, 24, 1, 32, 1, 40, 11, 50, 20, 46, + 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 65, 110, 121, + 82, 5, 118, 97, 108, 117, 101>> + ) + end + + field :value, 1, type: Google.Protobuf.Any +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityStreamOut do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + message: {atom, any} + } + defstruct [:message] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 20, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 83, 116, 114, 101, 97, 109, + 79, 117, 116, 18, 77, 10, 5, 114, 101, 112, 108, 121, 24, 1, 32, 1, 40, 11, 50, 53, 46, + 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, + 116, 111, 99, 111, 108, 46, 118, 97, 108, 117, 101, 101, 110, 116, 105, 116, 121, 46, 86, + 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 82, 101, 112, 108, 121, 72, 0, 82, 5, 114, + 101, 112, 108, 121, 18, 60, 10, 7, 102, 97, 105, 108, 117, 114, 101, 24, 2, 32, 1, 40, 11, + 50, 32, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, + 114, 111, 116, 111, 99, 111, 108, 46, 70, 97, 105, 108, 117, 114, 101, 72, 0, 82, 7, 102, + 97, 105, 108, 117, 114, 101, 66, 9, 10, 7, 109, 101, 115, 115, 97, 103, 101>> + ) + end + + oneof :message, 0 + field :reply, 1, type: Eigr.Functions.Protocol.Valueentity.ValueEntityReply, oneof: 0 + field :failure, 2, type: Eigr.Functions.Protocol.Failure, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityReply do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + command_id: integer, + client_action: Eigr.Functions.Protocol.ClientAction.t() | nil, + side_effects: [Eigr.Functions.Protocol.SideEffect.t()], + state_action: Eigr.Functions.Protocol.Valueentity.ValueEntityAction.t() | nil + } + defstruct [:command_id, :client_action, :side_effects, :state_action] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 16, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 82, 101, 112, 108, 121, 18, + 29, 10, 10, 99, 111, 109, 109, 97, 110, 100, 95, 105, 100, 24, 1, 32, 1, 40, 3, 82, 9, 99, + 111, 109, 109, 97, 110, 100, 73, 100, 18, 74, 10, 13, 99, 108, 105, 101, 110, 116, 95, 97, + 99, 116, 105, 111, 110, 24, 2, 32, 1, 40, 11, 50, 37, 46, 101, 105, 103, 114, 46, 102, + 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 67, + 108, 105, 101, 110, 116, 65, 99, 116, 105, 111, 110, 82, 12, 99, 108, 105, 101, 110, 116, + 65, 99, 116, 105, 111, 110, 18, 70, 10, 12, 115, 105, 100, 101, 95, 101, 102, 102, 101, + 99, 116, 115, 24, 3, 32, 3, 40, 11, 50, 35, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, + 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 83, 105, 100, 101, + 69, 102, 102, 101, 99, 116, 82, 11, 115, 105, 100, 101, 69, 102, 102, 101, 99, 116, 115, + 18, 89, 10, 12, 115, 116, 97, 116, 101, 95, 97, 99, 116, 105, 111, 110, 24, 4, 32, 1, 40, + 11, 50, 54, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, + 112, 114, 111, 116, 111, 99, 111, 108, 46, 118, 97, 108, 117, 101, 101, 110, 116, 105, + 116, 121, 46, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 65, 99, 116, 105, 111, + 110, 82, 11, 115, 116, 97, 116, 101, 65, 99, 116, 105, 111, 110>> + ) + end + + field :command_id, 1, type: :int64 + field :client_action, 2, type: Eigr.Functions.Protocol.ClientAction + field :side_effects, 3, repeated: true, type: Eigr.Functions.Protocol.SideEffect + field :state_action, 4, type: Eigr.Functions.Protocol.Valueentity.ValueEntityAction +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityAction do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + action: {atom, any} + } + defstruct [:action] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 65, 99, 116, 105, 111, 110, + 18, 80, 10, 6, 117, 112, 100, 97, 116, 101, 24, 1, 32, 1, 40, 11, 50, 54, 46, 101, 105, + 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, + 111, 108, 46, 118, 97, 108, 117, 101, 101, 110, 116, 105, 116, 121, 46, 86, 97, 108, 117, + 101, 69, 110, 116, 105, 116, 121, 85, 112, 100, 97, 116, 101, 72, 0, 82, 6, 117, 112, 100, + 97, 116, 101, 18, 80, 10, 6, 100, 101, 108, 101, 116, 101, 24, 2, 32, 1, 40, 11, 50, 54, + 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, 110, 115, 46, 112, 114, 111, + 116, 111, 99, 111, 108, 46, 118, 97, 108, 117, 101, 101, 110, 116, 105, 116, 121, 46, 86, + 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 68, 101, 108, 101, 116, 101, 72, 0, 82, 6, + 100, 101, 108, 101, 116, 101, 66, 8, 10, 6, 97, 99, 116, 105, 111, 110>> + ) + end + + oneof :action, 0 + field :update, 1, type: Eigr.Functions.Protocol.Valueentity.ValueEntityUpdate, oneof: 0 + field :delete, 2, type: Eigr.Functions.Protocol.Valueentity.ValueEntityDelete, oneof: 0 +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityUpdate do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + value: Google.Protobuf.Any.t() | nil + } + defstruct [:value] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 85, 112, 100, 97, 116, 101, + 18, 42, 10, 5, 118, 97, 108, 117, 101, 24, 1, 32, 1, 40, 11, 50, 20, 46, 103, 111, 111, + 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 65, 110, 121, 82, 5, 118, + 97, 108, 117, 101>> + ) + end + + field :value, 1, type: Google.Protobuf.Any +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntityDelete do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{} + defstruct [] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 68, 101, 108, 101, 116, 101>> + ) + end +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntity.Service do + @moduledoc false + use GRPC.Service, name: "eigr.functions.protocol.valueentity.ValueEntity" + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.ServiceDescriptorProto.decode( + <<10, 11, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 18, 134, 1, 10, 6, 104, 97, + 110, 100, 108, 101, 18, 56, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, 111, + 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 118, 97, 108, 117, 101, 101, 110, + 116, 105, 116, 121, 46, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 83, 116, 114, + 101, 97, 109, 73, 110, 26, 57, 46, 101, 105, 103, 114, 46, 102, 117, 110, 99, 116, 105, + 111, 110, 115, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 118, 97, 108, 117, 101, 101, + 110, 116, 105, 116, 121, 46, 86, 97, 108, 117, 101, 69, 110, 116, 105, 116, 121, 83, 116, + 114, 101, 97, 109, 79, 117, 116, 34, 3, 136, 2, 0, 40, 1, 48, 1>> + ) + end + + rpc :handle, + stream(Eigr.Functions.Protocol.Valueentity.ValueEntityStreamIn), + stream(Eigr.Functions.Protocol.Valueentity.ValueEntityStreamOut) +end + +defmodule Eigr.Functions.Protocol.Valueentity.ValueEntity.Stub do + @moduledoc false + use GRPC.Stub, service: Eigr.Functions.Protocol.Valueentity.ValueEntity.Service +end diff --git a/apps/eigr_protocol/lib/eigr_protocol.ex b/apps/eigr_protocol/lib/eigr_protocol.ex new file mode 100644 index 0000000..1d7c917 --- /dev/null +++ b/apps/eigr_protocol/lib/eigr_protocol.ex @@ -0,0 +1,18 @@ +defmodule EigrProtocol do + @moduledoc """ + Documentation for `EigrProtocol`. + """ + + @doc """ + Hello world. + + ## Examples + + iex> EigrProtocol.hello() + :world + + """ + def hello do + :world + end +end diff --git a/apps/eigr_protocol/lib/google/api/annotations.pb.ex b/apps/eigr_protocol/lib/google/api/annotations.pb.ex new file mode 100644 index 0000000..e69de29 diff --git a/apps/eigr_protocol/lib/google/api/auth.pb.ex b/apps/eigr_protocol/lib/google/api/auth.pb.ex new file mode 100644 index 0000000..f2a05b9 --- /dev/null +++ b/apps/eigr_protocol/lib/google/api/auth.pb.ex @@ -0,0 +1,175 @@ +defmodule Google.Api.Authentication do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + rules: [Google.Api.AuthenticationRule.t()], + providers: [Google.Api.AuthProvider.t()] + } + defstruct [:rules, :providers] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 14, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 18, 52, 10, 5, + 114, 117, 108, 101, 115, 24, 3, 32, 3, 40, 11, 50, 30, 46, 103, 111, 111, 103, 108, 101, + 46, 97, 112, 105, 46, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, + 82, 117, 108, 101, 82, 5, 114, 117, 108, 101, 115, 18, 54, 10, 9, 112, 114, 111, 118, 105, + 100, 101, 114, 115, 24, 4, 32, 3, 40, 11, 50, 24, 46, 103, 111, 111, 103, 108, 101, 46, + 97, 112, 105, 46, 65, 117, 116, 104, 80, 114, 111, 118, 105, 100, 101, 114, 82, 9, 112, + 114, 111, 118, 105, 100, 101, 114, 115>> + ) + end + + field :rules, 3, repeated: true, type: Google.Api.AuthenticationRule + field :providers, 4, repeated: true, type: Google.Api.AuthProvider +end + +defmodule Google.Api.AuthenticationRule do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + selector: String.t(), + oauth: Google.Api.OAuthRequirements.t() | nil, + allow_without_credential: boolean, + requirements: [Google.Api.AuthRequirement.t()] + } + defstruct [:selector, :oauth, :allow_without_credential, :requirements] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 18, 65, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 105, 111, 110, 82, 117, 108, + 101, 18, 26, 10, 8, 115, 101, 108, 101, 99, 116, 111, 114, 24, 1, 32, 1, 40, 9, 82, 8, + 115, 101, 108, 101, 99, 116, 111, 114, 18, 51, 10, 5, 111, 97, 117, 116, 104, 24, 2, 32, + 1, 40, 11, 50, 29, 46, 103, 111, 111, 103, 108, 101, 46, 97, 112, 105, 46, 79, 65, 117, + 116, 104, 82, 101, 113, 117, 105, 114, 101, 109, 101, 110, 116, 115, 82, 5, 111, 97, 117, + 116, 104, 18, 56, 10, 24, 97, 108, 108, 111, 119, 95, 119, 105, 116, 104, 111, 117, 116, + 95, 99, 114, 101, 100, 101, 110, 116, 105, 97, 108, 24, 5, 32, 1, 40, 8, 82, 22, 97, 108, + 108, 111, 119, 87, 105, 116, 104, 111, 117, 116, 67, 114, 101, 100, 101, 110, 116, 105, + 97, 108, 18, 63, 10, 12, 114, 101, 113, 117, 105, 114, 101, 109, 101, 110, 116, 115, 24, + 7, 32, 3, 40, 11, 50, 27, 46, 103, 111, 111, 103, 108, 101, 46, 97, 112, 105, 46, 65, 117, + 116, 104, 82, 101, 113, 117, 105, 114, 101, 109, 101, 110, 116, 82, 12, 114, 101, 113, + 117, 105, 114, 101, 109, 101, 110, 116, 115>> + ) + end + + field :selector, 1, type: :string + field :oauth, 2, type: Google.Api.OAuthRequirements + field :allow_without_credential, 5, type: :bool + field :requirements, 7, repeated: true, type: Google.Api.AuthRequirement +end + +defmodule Google.Api.JwtLocation do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + in: {atom, any}, + value_prefix: String.t() + } + defstruct [:in, :value_prefix] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 11, 74, 119, 116, 76, 111, 99, 97, 116, 105, 111, 110, 18, 24, 10, 6, 104, 101, 97, + 100, 101, 114, 24, 1, 32, 1, 40, 9, 72, 0, 82, 6, 104, 101, 97, 100, 101, 114, 18, 22, 10, + 5, 113, 117, 101, 114, 121, 24, 2, 32, 1, 40, 9, 72, 0, 82, 5, 113, 117, 101, 114, 121, + 18, 33, 10, 12, 118, 97, 108, 117, 101, 95, 112, 114, 101, 102, 105, 120, 24, 3, 32, 1, + 40, 9, 82, 11, 118, 97, 108, 117, 101, 80, 114, 101, 102, 105, 120, 66, 4, 10, 2, 105, + 110>> + ) + end + + oneof :in, 0 + field :header, 1, type: :string, oneof: 0 + field :query, 2, type: :string, oneof: 0 + field :value_prefix, 3, type: :string +end + +defmodule Google.Api.AuthProvider do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + id: String.t(), + issuer: String.t(), + jwks_uri: String.t(), + audiences: String.t(), + authorization_url: String.t(), + jwt_locations: [Google.Api.JwtLocation.t()] + } + defstruct [:id, :issuer, :jwks_uri, :audiences, :authorization_url, :jwt_locations] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 12, 65, 117, 116, 104, 80, 114, 111, 118, 105, 100, 101, 114, 18, 14, 10, 2, 105, 100, + 24, 1, 32, 1, 40, 9, 82, 2, 105, 100, 18, 22, 10, 6, 105, 115, 115, 117, 101, 114, 24, 2, + 32, 1, 40, 9, 82, 6, 105, 115, 115, 117, 101, 114, 18, 25, 10, 8, 106, 119, 107, 115, 95, + 117, 114, 105, 24, 3, 32, 1, 40, 9, 82, 7, 106, 119, 107, 115, 85, 114, 105, 18, 28, 10, + 9, 97, 117, 100, 105, 101, 110, 99, 101, 115, 24, 4, 32, 1, 40, 9, 82, 9, 97, 117, 100, + 105, 101, 110, 99, 101, 115, 18, 43, 10, 17, 97, 117, 116, 104, 111, 114, 105, 122, 97, + 116, 105, 111, 110, 95, 117, 114, 108, 24, 5, 32, 1, 40, 9, 82, 16, 97, 117, 116, 104, + 111, 114, 105, 122, 97, 116, 105, 111, 110, 85, 114, 108, 18, 60, 10, 13, 106, 119, 116, + 95, 108, 111, 99, 97, 116, 105, 111, 110, 115, 24, 6, 32, 3, 40, 11, 50, 23, 46, 103, 111, + 111, 103, 108, 101, 46, 97, 112, 105, 46, 74, 119, 116, 76, 111, 99, 97, 116, 105, 111, + 110, 82, 12, 106, 119, 116, 76, 111, 99, 97, 116, 105, 111, 110, 115>> + ) + end + + field :id, 1, type: :string + field :issuer, 2, type: :string + field :jwks_uri, 3, type: :string + field :audiences, 4, type: :string + field :authorization_url, 5, type: :string + field :jwt_locations, 6, repeated: true, type: Google.Api.JwtLocation +end + +defmodule Google.Api.OAuthRequirements do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + canonical_scopes: String.t() + } + defstruct [:canonical_scopes] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 79, 65, 117, 116, 104, 82, 101, 113, 117, 105, 114, 101, 109, 101, 110, 116, 115, + 18, 41, 10, 16, 99, 97, 110, 111, 110, 105, 99, 97, 108, 95, 115, 99, 111, 112, 101, 115, + 24, 1, 32, 1, 40, 9, 82, 15, 99, 97, 110, 111, 110, 105, 99, 97, 108, 83, 99, 111, 112, + 101, 115>> + ) + end + + field :canonical_scopes, 1, type: :string +end + +defmodule Google.Api.AuthRequirement do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + provider_id: String.t(), + audiences: String.t() + } + defstruct [:provider_id, :audiences] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 15, 65, 117, 116, 104, 82, 101, 113, 117, 105, 114, 101, 109, 101, 110, 116, 18, 31, + 10, 11, 112, 114, 111, 118, 105, 100, 101, 114, 95, 105, 100, 24, 1, 32, 1, 40, 9, 82, 10, + 112, 114, 111, 118, 105, 100, 101, 114, 73, 100, 18, 28, 10, 9, 97, 117, 100, 105, 101, + 110, 99, 101, 115, 24, 2, 32, 1, 40, 9, 82, 9, 97, 117, 100, 105, 101, 110, 99, 101, 115>> + ) + end + + field :provider_id, 1, type: :string + field :audiences, 2, type: :string +end diff --git a/apps/eigr_protocol/lib/google/api/http.pb.ex b/apps/eigr_protocol/lib/google/api/http.pb.ex new file mode 100644 index 0000000..ba11776 --- /dev/null +++ b/apps/eigr_protocol/lib/google/api/http.pb.ex @@ -0,0 +1,98 @@ +defmodule Google.Api.Http do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + rules: [Google.Api.HttpRule.t()], + fully_decode_reserved_expansion: boolean + } + defstruct [:rules, :fully_decode_reserved_expansion] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 4, 72, 116, 116, 112, 18, 42, 10, 5, 114, 117, 108, 101, 115, 24, 1, 32, 3, 40, 11, + 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 97, 112, 105, 46, 72, 116, 116, 112, 82, + 117, 108, 101, 82, 5, 114, 117, 108, 101, 115, 18, 69, 10, 31, 102, 117, 108, 108, 121, + 95, 100, 101, 99, 111, 100, 101, 95, 114, 101, 115, 101, 114, 118, 101, 100, 95, 101, 120, + 112, 97, 110, 115, 105, 111, 110, 24, 2, 32, 1, 40, 8, 82, 28, 102, 117, 108, 108, 121, + 68, 101, 99, 111, 100, 101, 82, 101, 115, 101, 114, 118, 101, 100, 69, 120, 112, 97, 110, + 115, 105, 111, 110>> + ) + end + + field :rules, 1, repeated: true, type: Google.Api.HttpRule + field :fully_decode_reserved_expansion, 2, type: :bool +end + +defmodule Google.Api.HttpRule do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + pattern: {atom, any}, + selector: String.t(), + body: String.t(), + response_body: String.t(), + additional_bindings: [Google.Api.HttpRule.t()] + } + defstruct [:pattern, :selector, :body, :response_body, :additional_bindings] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 8, 72, 116, 116, 112, 82, 117, 108, 101, 18, 26, 10, 8, 115, 101, 108, 101, 99, 116, + 111, 114, 24, 1, 32, 1, 40, 9, 82, 8, 115, 101, 108, 101, 99, 116, 111, 114, 18, 18, 10, + 3, 103, 101, 116, 24, 2, 32, 1, 40, 9, 72, 0, 82, 3, 103, 101, 116, 18, 18, 10, 3, 112, + 117, 116, 24, 3, 32, 1, 40, 9, 72, 0, 82, 3, 112, 117, 116, 18, 20, 10, 4, 112, 111, 115, + 116, 24, 4, 32, 1, 40, 9, 72, 0, 82, 4, 112, 111, 115, 116, 18, 24, 10, 6, 100, 101, 108, + 101, 116, 101, 24, 5, 32, 1, 40, 9, 72, 0, 82, 6, 100, 101, 108, 101, 116, 101, 18, 22, + 10, 5, 112, 97, 116, 99, 104, 24, 6, 32, 1, 40, 9, 72, 0, 82, 5, 112, 97, 116, 99, 104, + 18, 55, 10, 6, 99, 117, 115, 116, 111, 109, 24, 8, 32, 1, 40, 11, 50, 29, 46, 103, 111, + 111, 103, 108, 101, 46, 97, 112, 105, 46, 67, 117, 115, 116, 111, 109, 72, 116, 116, 112, + 80, 97, 116, 116, 101, 114, 110, 72, 0, 82, 6, 99, 117, 115, 116, 111, 109, 18, 18, 10, 4, + 98, 111, 100, 121, 24, 7, 32, 1, 40, 9, 82, 4, 98, 111, 100, 121, 18, 35, 10, 13, 114, + 101, 115, 112, 111, 110, 115, 101, 95, 98, 111, 100, 121, 24, 12, 32, 1, 40, 9, 82, 12, + 114, 101, 115, 112, 111, 110, 115, 101, 66, 111, 100, 121, 18, 69, 10, 19, 97, 100, 100, + 105, 116, 105, 111, 110, 97, 108, 95, 98, 105, 110, 100, 105, 110, 103, 115, 24, 11, 32, + 3, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 97, 112, 105, 46, 72, 116, 116, + 112, 82, 117, 108, 101, 82, 18, 97, 100, 100, 105, 116, 105, 111, 110, 97, 108, 66, 105, + 110, 100, 105, 110, 103, 115, 66, 9, 10, 7, 112, 97, 116, 116, 101, 114, 110>> + ) + end + + oneof :pattern, 0 + field :selector, 1, type: :string + field :get, 2, type: :string, oneof: 0 + field :put, 3, type: :string, oneof: 0 + field :post, 4, type: :string, oneof: 0 + field :delete, 5, type: :string, oneof: 0 + field :patch, 6, type: :string, oneof: 0 + field :custom, 8, type: Google.Api.CustomHttpPattern, oneof: 0 + field :body, 7, type: :string + field :response_body, 12, type: :string + field :additional_bindings, 11, repeated: true, type: Google.Api.HttpRule +end + +defmodule Google.Api.CustomHttpPattern do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + kind: String.t(), + path: String.t() + } + defstruct [:kind, :path] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 17, 67, 117, 115, 116, 111, 109, 72, 116, 116, 112, 80, 97, 116, 116, 101, 114, 110, + 18, 18, 10, 4, 107, 105, 110, 100, 24, 1, 32, 1, 40, 9, 82, 4, 107, 105, 110, 100, 18, 18, + 10, 4, 112, 97, 116, 104, 24, 2, 32, 1, 40, 9, 82, 4, 112, 97, 116, 104>> + ) + end + + field :kind, 1, type: :string + field :path, 2, type: :string +end diff --git a/apps/eigr_protocol/lib/google/api/httpbody.pb.ex b/apps/eigr_protocol/lib/google/api/httpbody.pb.ex new file mode 100644 index 0000000..fe675e8 --- /dev/null +++ b/apps/eigr_protocol/lib/google/api/httpbody.pb.ex @@ -0,0 +1,27 @@ +defmodule Google.Api.HttpBody do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + content_type: String.t(), + data: binary, + extensions: [Google.Protobuf.Any.t()] + } + defstruct [:content_type, :data, :extensions] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 8, 72, 116, 116, 112, 66, 111, 100, 121, 18, 33, 10, 12, 99, 111, 110, 116, 101, 110, + 116, 95, 116, 121, 112, 101, 24, 1, 32, 1, 40, 9, 82, 11, 99, 111, 110, 116, 101, 110, + 116, 84, 121, 112, 101, 18, 18, 10, 4, 100, 97, 116, 97, 24, 2, 32, 1, 40, 12, 82, 4, 100, + 97, 116, 97, 18, 52, 10, 10, 101, 120, 116, 101, 110, 115, 105, 111, 110, 115, 24, 3, 32, + 3, 40, 11, 50, 20, 46, 103, 111, 111, 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, + 102, 46, 65, 110, 121, 82, 10, 101, 120, 116, 101, 110, 115, 105, 111, 110, 115>> + ) + end + + field :content_type, 1, type: :string + field :data, 2, type: :bytes + field :extensions, 3, repeated: true, type: Google.Protobuf.Any +end diff --git a/apps/eigr_protocol/lib/google/api/source_info.pb.ex b/apps/eigr_protocol/lib/google/api/source_info.pb.ex new file mode 100644 index 0000000..c2121b0 --- /dev/null +++ b/apps/eigr_protocol/lib/google/api/source_info.pb.ex @@ -0,0 +1,21 @@ +defmodule Google.Api.SourceInfo do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + source_files: [Google.Protobuf.Any.t()] + } + defstruct [:source_files] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 10, 83, 111, 117, 114, 99, 101, 73, 110, 102, 111, 18, 55, 10, 12, 115, 111, 117, 114, + 99, 101, 95, 102, 105, 108, 101, 115, 24, 1, 32, 3, 40, 11, 50, 20, 46, 103, 111, 111, + 103, 108, 101, 46, 112, 114, 111, 116, 111, 98, 117, 102, 46, 65, 110, 121, 82, 11, 115, + 111, 117, 114, 99, 101, 70, 105, 108, 101, 115>> + ) + end + + field :source_files, 1, repeated: true, type: Google.Protobuf.Any +end diff --git a/apps/eigr_protocol/lib/grpc/reflection/v1alpha/reflection.pb.ex b/apps/eigr_protocol/lib/grpc/reflection/v1alpha/reflection.pb.ex new file mode 100644 index 0000000..9fb40bc --- /dev/null +++ b/apps/eigr_protocol/lib/grpc/reflection/v1alpha/reflection.pb.ex @@ -0,0 +1,278 @@ +defmodule Grpc.Reflection.V1alpha.ServerReflectionRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + message_request: {atom, any}, + host: String.t() + } + defstruct [:message_request, :host] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 23, 83, 101, 114, 118, 101, 114, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 82, + 101, 113, 117, 101, 115, 116, 18, 18, 10, 4, 104, 111, 115, 116, 24, 1, 32, 1, 40, 9, 82, + 4, 104, 111, 115, 116, 18, 42, 10, 16, 102, 105, 108, 101, 95, 98, 121, 95, 102, 105, 108, + 101, 110, 97, 109, 101, 24, 3, 32, 1, 40, 9, 72, 0, 82, 14, 102, 105, 108, 101, 66, 121, + 70, 105, 108, 101, 110, 97, 109, 101, 18, 54, 10, 22, 102, 105, 108, 101, 95, 99, 111, + 110, 116, 97, 105, 110, 105, 110, 103, 95, 115, 121, 109, 98, 111, 108, 24, 4, 32, 1, 40, + 9, 72, 0, 82, 20, 102, 105, 108, 101, 67, 111, 110, 116, 97, 105, 110, 105, 110, 103, 83, + 121, 109, 98, 111, 108, 18, 103, 10, 25, 102, 105, 108, 101, 95, 99, 111, 110, 116, 97, + 105, 110, 105, 110, 103, 95, 101, 120, 116, 101, 110, 115, 105, 111, 110, 24, 5, 32, 1, + 40, 11, 50, 41, 46, 103, 114, 112, 99, 46, 114, 101, 102, 108, 101, 99, 116, 105, 111, + 110, 46, 118, 49, 97, 108, 112, 104, 97, 46, 69, 120, 116, 101, 110, 115, 105, 111, 110, + 82, 101, 113, 117, 101, 115, 116, 72, 0, 82, 23, 102, 105, 108, 101, 67, 111, 110, 116, + 97, 105, 110, 105, 110, 103, 69, 120, 116, 101, 110, 115, 105, 111, 110, 18, 66, 10, 29, + 97, 108, 108, 95, 101, 120, 116, 101, 110, 115, 105, 111, 110, 95, 110, 117, 109, 98, 101, + 114, 115, 95, 111, 102, 95, 116, 121, 112, 101, 24, 6, 32, 1, 40, 9, 72, 0, 82, 25, 97, + 108, 108, 69, 120, 116, 101, 110, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 115, 79, + 102, 84, 121, 112, 101, 18, 37, 10, 13, 108, 105, 115, 116, 95, 115, 101, 114, 118, 105, + 99, 101, 115, 24, 7, 32, 1, 40, 9, 72, 0, 82, 12, 108, 105, 115, 116, 83, 101, 114, 118, + 105, 99, 101, 115, 66, 17, 10, 15, 109, 101, 115, 115, 97, 103, 101, 95, 114, 101, 113, + 117, 101, 115, 116>> + ) + end + + oneof :message_request, 0 + field :host, 1, type: :string + field :file_by_filename, 3, type: :string, oneof: 0 + field :file_containing_symbol, 4, type: :string, oneof: 0 + field :file_containing_extension, 5, type: Grpc.Reflection.V1alpha.ExtensionRequest, oneof: 0 + field :all_extension_numbers_of_type, 6, type: :string, oneof: 0 + field :list_services, 7, type: :string, oneof: 0 +end + +defmodule Grpc.Reflection.V1alpha.ExtensionRequest do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + containing_type: String.t(), + extension_number: integer + } + defstruct [:containing_type, :extension_number] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 16, 69, 120, 116, 101, 110, 115, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 18, + 39, 10, 15, 99, 111, 110, 116, 97, 105, 110, 105, 110, 103, 95, 116, 121, 112, 101, 24, 1, + 32, 1, 40, 9, 82, 14, 99, 111, 110, 116, 97, 105, 110, 105, 110, 103, 84, 121, 112, 101, + 18, 41, 10, 16, 101, 120, 116, 101, 110, 115, 105, 111, 110, 95, 110, 117, 109, 98, 101, + 114, 24, 2, 32, 1, 40, 5, 82, 15, 101, 120, 116, 101, 110, 115, 105, 111, 110, 78, 117, + 109, 98, 101, 114>> + ) + end + + field :containing_type, 1, type: :string + field :extension_number, 2, type: :int32 +end + +defmodule Grpc.Reflection.V1alpha.ServerReflectionResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + message_response: {atom, any}, + valid_host: String.t(), + original_request: Grpc.Reflection.V1alpha.ServerReflectionRequest.t() | nil + } + defstruct [:message_response, :valid_host, :original_request] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 24, 83, 101, 114, 118, 101, 114, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 82, + 101, 115, 112, 111, 110, 115, 101, 18, 29, 10, 10, 118, 97, 108, 105, 100, 95, 104, 111, + 115, 116, 24, 1, 32, 1, 40, 9, 82, 9, 118, 97, 108, 105, 100, 72, 111, 115, 116, 18, 91, + 10, 16, 111, 114, 105, 103, 105, 110, 97, 108, 95, 114, 101, 113, 117, 101, 115, 116, 24, + 2, 32, 1, 40, 11, 50, 48, 46, 103, 114, 112, 99, 46, 114, 101, 102, 108, 101, 99, 116, + 105, 111, 110, 46, 118, 49, 97, 108, 112, 104, 97, 46, 83, 101, 114, 118, 101, 114, 82, + 101, 102, 108, 101, 99, 116, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 82, 15, 111, + 114, 105, 103, 105, 110, 97, 108, 82, 101, 113, 117, 101, 115, 116, 18, 107, 10, 24, 102, + 105, 108, 101, 95, 100, 101, 115, 99, 114, 105, 112, 116, 111, 114, 95, 114, 101, 115, + 112, 111, 110, 115, 101, 24, 4, 32, 1, 40, 11, 50, 47, 46, 103, 114, 112, 99, 46, 114, + 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 118, 49, 97, 108, 112, 104, 97, 46, 70, + 105, 108, 101, 68, 101, 115, 99, 114, 105, 112, 116, 111, 114, 82, 101, 115, 112, 111, + 110, 115, 101, 72, 0, 82, 22, 102, 105, 108, 101, 68, 101, 115, 99, 114, 105, 112, 116, + 111, 114, 82, 101, 115, 112, 111, 110, 115, 101, 18, 119, 10, 30, 97, 108, 108, 95, 101, + 120, 116, 101, 110, 115, 105, 111, 110, 95, 110, 117, 109, 98, 101, 114, 115, 95, 114, + 101, 115, 112, 111, 110, 115, 101, 24, 5, 32, 1, 40, 11, 50, 48, 46, 103, 114, 112, 99, + 46, 114, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 118, 49, 97, 108, 112, 104, 97, + 46, 69, 120, 116, 101, 110, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 82, 101, 115, + 112, 111, 110, 115, 101, 72, 0, 82, 27, 97, 108, 108, 69, 120, 116, 101, 110, 115, 105, + 111, 110, 78, 117, 109, 98, 101, 114, 115, 82, 101, 115, 112, 111, 110, 115, 101, 18, 100, + 10, 22, 108, 105, 115, 116, 95, 115, 101, 114, 118, 105, 99, 101, 115, 95, 114, 101, 115, + 112, 111, 110, 115, 101, 24, 6, 32, 1, 40, 11, 50, 44, 46, 103, 114, 112, 99, 46, 114, + 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 118, 49, 97, 108, 112, 104, 97, 46, 76, + 105, 115, 116, 83, 101, 114, 118, 105, 99, 101, 82, 101, 115, 112, 111, 110, 115, 101, 72, + 0, 82, 20, 108, 105, 115, 116, 83, 101, 114, 118, 105, 99, 101, 115, 82, 101, 115, 112, + 111, 110, 115, 101, 18, 79, 10, 14, 101, 114, 114, 111, 114, 95, 114, 101, 115, 112, 111, + 110, 115, 101, 24, 7, 32, 1, 40, 11, 50, 38, 46, 103, 114, 112, 99, 46, 114, 101, 102, + 108, 101, 99, 116, 105, 111, 110, 46, 118, 49, 97, 108, 112, 104, 97, 46, 69, 114, 114, + 111, 114, 82, 101, 115, 112, 111, 110, 115, 101, 72, 0, 82, 13, 101, 114, 114, 111, 114, + 82, 101, 115, 112, 111, 110, 115, 101, 66, 18, 10, 16, 109, 101, 115, 115, 97, 103, 101, + 95, 114, 101, 115, 112, 111, 110, 115, 101>> + ) + end + + oneof :message_response, 0 + field :valid_host, 1, type: :string + field :original_request, 2, type: Grpc.Reflection.V1alpha.ServerReflectionRequest + + field :file_descriptor_response, 4, + type: Grpc.Reflection.V1alpha.FileDescriptorResponse, + oneof: 0 + + field :all_extension_numbers_response, 5, + type: Grpc.Reflection.V1alpha.ExtensionNumberResponse, + oneof: 0 + + field :list_services_response, 6, type: Grpc.Reflection.V1alpha.ListServiceResponse, oneof: 0 + field :error_response, 7, type: Grpc.Reflection.V1alpha.ErrorResponse, oneof: 0 +end + +defmodule Grpc.Reflection.V1alpha.FileDescriptorResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + file_descriptor_proto: [binary] + } + defstruct [:file_descriptor_proto] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 22, 70, 105, 108, 101, 68, 101, 115, 99, 114, 105, 112, 116, 111, 114, 82, 101, 115, + 112, 111, 110, 115, 101, 18, 50, 10, 21, 102, 105, 108, 101, 95, 100, 101, 115, 99, 114, + 105, 112, 116, 111, 114, 95, 112, 114, 111, 116, 111, 24, 1, 32, 3, 40, 12, 82, 19, 102, + 105, 108, 101, 68, 101, 115, 99, 114, 105, 112, 116, 111, 114, 80, 114, 111, 116, 111>> + ) + end + + field :file_descriptor_proto, 1, repeated: true, type: :bytes +end + +defmodule Grpc.Reflection.V1alpha.ExtensionNumberResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + base_type_name: String.t(), + extension_number: [integer] + } + defstruct [:base_type_name, :extension_number] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 23, 69, 120, 116, 101, 110, 115, 105, 111, 110, 78, 117, 109, 98, 101, 114, 82, 101, + 115, 112, 111, 110, 115, 101, 18, 36, 10, 14, 98, 97, 115, 101, 95, 116, 121, 112, 101, + 95, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 12, 98, 97, 115, 101, 84, 121, 112, 101, + 78, 97, 109, 101, 18, 41, 10, 16, 101, 120, 116, 101, 110, 115, 105, 111, 110, 95, 110, + 117, 109, 98, 101, 114, 24, 2, 32, 3, 40, 5, 82, 15, 101, 120, 116, 101, 110, 115, 105, + 111, 110, 78, 117, 109, 98, 101, 114>> + ) + end + + field :base_type_name, 1, type: :string + field :extension_number, 2, repeated: true, type: :int32 +end + +defmodule Grpc.Reflection.V1alpha.ListServiceResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + service: [Grpc.Reflection.V1alpha.ServiceResponse.t()] + } + defstruct [:service] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 19, 76, 105, 115, 116, 83, 101, 114, 118, 105, 99, 101, 82, 101, 115, 112, 111, 110, + 115, 101, 18, 66, 10, 7, 115, 101, 114, 118, 105, 99, 101, 24, 1, 32, 3, 40, 11, 50, 40, + 46, 103, 114, 112, 99, 46, 114, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 118, 49, + 97, 108, 112, 104, 97, 46, 83, 101, 114, 118, 105, 99, 101, 82, 101, 115, 112, 111, 110, + 115, 101, 82, 7, 115, 101, 114, 118, 105, 99, 101>> + ) + end + + field :service, 1, repeated: true, type: Grpc.Reflection.V1alpha.ServiceResponse +end + +defmodule Grpc.Reflection.V1alpha.ServiceResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + name: String.t() + } + defstruct [:name] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 15, 83, 101, 114, 118, 105, 99, 101, 82, 101, 115, 112, 111, 110, 115, 101, 18, 18, + 10, 4, 110, 97, 109, 101, 24, 1, 32, 1, 40, 9, 82, 4, 110, 97, 109, 101>> + ) + end + + field :name, 1, type: :string +end + +defmodule Grpc.Reflection.V1alpha.ErrorResponse do + @moduledoc false + use Protobuf, syntax: :proto3 + + @type t :: %__MODULE__{ + error_code: integer, + error_message: String.t() + } + defstruct [:error_code, :error_message] + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.DescriptorProto.decode( + <<10, 13, 69, 114, 114, 111, 114, 82, 101, 115, 112, 111, 110, 115, 101, 18, 29, 10, 10, + 101, 114, 114, 111, 114, 95, 99, 111, 100, 101, 24, 1, 32, 1, 40, 5, 82, 9, 101, 114, 114, + 111, 114, 67, 111, 100, 101, 18, 35, 10, 13, 101, 114, 114, 111, 114, 95, 109, 101, 115, + 115, 97, 103, 101, 24, 2, 32, 1, 40, 9, 82, 12, 101, 114, 114, 111, 114, 77, 101, 115, + 115, 97, 103, 101>> + ) + end + + field :error_code, 1, type: :int32 + field :error_message, 2, type: :string +end + +defmodule Grpc.Reflection.V1alpha.ServerReflection.Service do + @moduledoc false + use GRPC.Service, name: "grpc.reflection.v1alpha.ServerReflection" + + def descriptor do + # credo:disable-for-next-line + Elixir.Google.Protobuf.ServiceDescriptorProto.decode( + <<10, 16, 83, 101, 114, 118, 101, 114, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 18, + 127, 10, 20, 83, 101, 114, 118, 101, 114, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, + 73, 110, 102, 111, 18, 48, 46, 103, 114, 112, 99, 46, 114, 101, 102, 108, 101, 99, 116, + 105, 111, 110, 46, 118, 49, 97, 108, 112, 104, 97, 46, 83, 101, 114, 118, 101, 114, 82, + 101, 102, 108, 101, 99, 116, 105, 111, 110, 82, 101, 113, 117, 101, 115, 116, 26, 49, 46, + 103, 114, 112, 99, 46, 114, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 118, 49, 97, + 108, 112, 104, 97, 46, 83, 101, 114, 118, 101, 114, 82, 101, 102, 108, 101, 99, 116, 105, + 111, 110, 82, 101, 115, 112, 111, 110, 115, 101, 40, 1, 48, 1>> + ) + end + + rpc :ServerReflectionInfo, + stream(Grpc.Reflection.V1alpha.ServerReflectionRequest), + stream(Grpc.Reflection.V1alpha.ServerReflectionResponse) +end + +defmodule Grpc.Reflection.V1alpha.ServerReflection.Stub do + @moduledoc false + use GRPC.Stub, service: Grpc.Reflection.V1alpha.ServerReflection.Service +end diff --git a/apps/eigr_protocol/mix.exs b/apps/eigr_protocol/mix.exs new file mode 100644 index 0000000..a2671b0 --- /dev/null +++ b/apps/eigr_protocol/mix.exs @@ -0,0 +1,34 @@ +defmodule EigrProtocol.MixProject do + use Mix.Project + + def project do + [ + app: :eigr_protocol, + version: "0.1.0", + build_path: "../../_build", + config_path: "../../config/config.exs", + deps_path: "../../deps", + lockfile: "../../mix.lock", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:google_protos, "~> 0.2.0"}, + {:protobuf, "~> 0.9.0", override: true}, + {:grpc, github: "elixir-grpc/grpc", override: true}, + {:cowlib, "~> 2.11", override: true} + ] + end +end diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/example/shoppingcart/persistence/domain.proto b/apps/eigr_protocol/priv/protos/eigr/functions/example/shoppingcart/persistence/domain.proto new file mode 100644 index 0000000..c827b80 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/example/shoppingcart/persistence/domain.proto @@ -0,0 +1,27 @@ +// These are the messages that get persisted - the events, plus the current state (Cart) for snapshots. +syntax = "proto3"; + +package com.example.shoppingcart.persistence; + +option go_package = "persistence"; + +message LineItem { + string productId = 1; + string name = 2; + int32 quantity = 3; +} + +// The item added event. +message ItemAdded { + LineItem item = 1; +} + +// The item removed event. +message ItemRemoved { + string productId = 1; +} + +// The shopping cart state. +message Cart { + repeated LineItem items = 1; +} diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/example/shoppingcart/shoppingcart.proto b/apps/eigr_protocol/priv/protos/eigr/functions/example/shoppingcart/shoppingcart.proto new file mode 100644 index 0000000..27e1baf --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/example/shoppingcart/shoppingcart.proto @@ -0,0 +1,63 @@ +// This is the public API offered by the shopping cart entity. +syntax = "proto3"; + +import "google/protobuf/empty.proto"; +import "cloudstate/entity_key.proto"; +import "cloudstate/eventing.proto"; +import "google/api/annotations.proto"; +import "google/api/http.proto"; +import "google/api/httpbody.proto"; + +package com.example.shoppingcart; + +option go_package = "tck/shoppingcart"; + +message AddLineItem { + string user_id = 1 [(.cloudstate.entity_key) = true]; + string product_id = 2; + string name = 3; + int32 quantity = 4; +} + +message RemoveLineItem { + string user_id = 1 [(.cloudstate.entity_key) = true]; + string product_id = 2; +} + +message GetShoppingCart { + string user_id = 1 [(.cloudstate.entity_key) = true]; +} + +message LineItem { + string product_id = 1; + string name = 2; + int32 quantity = 3; +} + +message Cart { + repeated LineItem items = 1; +} + +service ShoppingCart { + rpc AddItem(AddLineItem) returns (google.protobuf.Empty) { + option (google.api.http) = { + post: "/cart/{user_id}/items/add", + body: "*", + }; + option (.cloudstate.eventing).in = "items"; + } + + rpc RemoveItem(RemoveLineItem) returns (google.protobuf.Empty) { + option (google.api.http).post = "/cart/{user_id}/items/{product_id}/remove"; + } + + rpc GetCart(GetShoppingCart) returns (Cart) { + option (google.api.http) = { + get: "/carts/{user_id}", + additional_bindings: { + get: "/carts/{user_id}/items", + response_body: "items" + } + }; + } +} diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/annotations.proto b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/annotations.proto new file mode 100644 index 0000000..f7bcab1 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/annotations.proto @@ -0,0 +1,32 @@ +// Copyright (c) 2015, Google Inc. +// +// 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. + +syntax = "proto3"; + +package google.api; + +import "google/api/http.proto"; +import "google/protobuf/descriptor.proto"; + +option csharp_namespace = "Google.Protobuf"; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "AnnotationsProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +extend google.protobuf.MethodOptions { + // See `HttpRule`. + HttpRule http = 72295728; +} diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/auth.proto b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/auth.proto new file mode 100644 index 0000000..1a1cf26 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/auth.proto @@ -0,0 +1,228 @@ +// Copyright 2020 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 +// +// 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. + +syntax = "proto3"; + +package google.api; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "AuthProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// `Authentication` defines the authentication configuration for an API. +// +// Example for an API targeted for external use: +// +// name: calendar.googleapis.com +// authentication: +// providers: +// - id: google_calendar_auth +// jwks_uri: https://www.googleapis.com/oauth2/v1/certs +// issuer: https://securetoken.google.com +// rules: +// - selector: "*" +// requirements: +// provider_id: google_calendar_auth +message Authentication { + // A list of authentication rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated AuthenticationRule rules = 3; + + // Defines a set of authentication providers that a service supports. + repeated AuthProvider providers = 4; +} + +// Authentication rules for the service. +// +// By default, if a method has any authentication requirements, every request +// must include a valid credential matching one of the requirements. +// It's an error to include more than one kind of credential in a single +// request. +// +// If a method doesn't have any auth requirements, request credentials will be +// ignored. +message AuthenticationRule { + // Selects the methods to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // The requirements for OAuth credentials. + OAuthRequirements oauth = 2; + + // If true, the service accepts API keys without any other credential. + // This flag only applies to HTTP and gRPC requests. + bool allow_without_credential = 5; + + // Requirements for additional authentication providers. + repeated AuthRequirement requirements = 7; +} + +// Specifies a location to extract JWT from an API request. +message JwtLocation { + oneof in { + // Specifies HTTP header name to extract JWT token. + string header = 1; + + // Specifies URL query parameter name to extract JWT token. + string query = 2; + } + + // The value prefix. The value format is "value_prefix{token}" + // Only applies to "in" header type. Must be empty for "in" query type. + // If not empty, the header value has to match (case sensitive) this prefix. + // If not matched, JWT will not be extracted. If matched, JWT will be + // extracted after the prefix is removed. + // + // For example, for "Authorization: Bearer {JWT}", + // value_prefix="Bearer " with a space at the end. + string value_prefix = 3; +} + +// Configuration for an authentication provider, including support for +// [JSON Web Token +// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32). +message AuthProvider { + // The unique identifier of the auth provider. It will be referred to by + // `AuthRequirement.provider_id`. + // + // Example: "bookstore_auth". + string id = 1; + + // Identifies the principal that issued the JWT. See + // https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.1 + // Usually a URL or an email address. + // + // Example: https://securetoken.google.com + // Example: 1234567-compute@developer.gserviceaccount.com + string issuer = 2; + + // URL of the provider's public key set to validate signature of the JWT. See + // [OpenID + // Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). + // Optional if the key set document: + // - can be retrieved from + // [OpenID + // Discovery](https://openid.net/specs/openid-connect-discovery-1_0.html) + // of the issuer. + // - can be inferred from the email domain of the issuer (e.g. a Google + // service account). + // + // Example: https://www.googleapis.com/oauth2/v1/certs + string jwks_uri = 3; + + // The list of JWT + // [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). + // that are allowed to access. A JWT containing any of these audiences will + // be accepted. When this setting is absent, JWTs with audiences: + // - "https://[service.name]/[google.protobuf.Api.name]" + // - "https://[service.name]/" + // will be accepted. + // For example, if no audiences are in the setting, LibraryService API will + // accept JWTs with the following audiences: + // - + // https://library-example.googleapis.com/google.example.library.v1.LibraryService + // - https://library-example.googleapis.com/ + // + // Example: + // + // audiences: bookstore_android.apps.googleusercontent.com, + // bookstore_web.apps.googleusercontent.com + string audiences = 4; + + // Redirect URL if JWT token is required but not present or is expired. + // Implement authorizationUrl of securityDefinitions in OpenAPI spec. + string authorization_url = 5; + + // Defines the locations to extract the JWT. + // + // JWT locations can be either from HTTP headers or URL query parameters. + // The rule is that the first match wins. The checking order is: checking + // all headers first, then URL query parameters. + // + // If not specified, default to use following 3 locations: + // 1) Authorization: Bearer + // 2) x-goog-iap-jwt-assertion + // 3) access_token query parameter + // + // Default locations can be specified as followings: + // jwt_locations: + // - header: Authorization + // value_prefix: "Bearer " + // - header: x-goog-iap-jwt-assertion + // - query: access_token + repeated JwtLocation jwt_locations = 6; +} + +// OAuth scopes are a way to define data and permissions on data. For example, +// there are scopes defined for "Read-only access to Google Calendar" and +// "Access to Cloud Platform". Users can consent to a scope for an application, +// giving it permission to access that data on their behalf. +// +// OAuth scope specifications should be fairly coarse grained; a user will need +// to see and understand the text description of what your scope means. +// +// In most cases: use one or at most two OAuth scopes for an entire family of +// products. If your product has multiple APIs, you should probably be sharing +// the OAuth scope across all of those APIs. +// +// When you need finer grained OAuth consent screens: talk with your product +// management about how developers will use them in practice. +// +// Please note that even though each of the canonical scopes is enough for a +// request to be accepted and passed to the backend, a request can still fail +// due to the backend requiring additional scopes or permissions. +message OAuthRequirements { + // The list of publicly documented OAuth scopes that are allowed access. An + // OAuth token containing any of these scopes will be accepted. + // + // Example: + // + // canonical_scopes: https://www.googleapis.com/auth/calendar, + // https://www.googleapis.com/auth/calendar.read + string canonical_scopes = 1; +} + +// User-defined authentication requirements, including support for +// [JSON Web Token +// (JWT)](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32). +message AuthRequirement { + // [id][google.api.AuthProvider.id] from authentication provider. + // + // Example: + // + // provider_id: bookstore_auth + string provider_id = 1; + + // NOTE: This will be deprecated soon, once AuthProvider.audiences is + // implemented and accepted in all the runtime components. + // + // The list of JWT + // [audiences](https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.3). + // that are allowed to access. A JWT containing any of these audiences will + // be accepted. When this setting is absent, only JWTs with audience + // "https://[Service_name][google.api.Service.name]/[API_name][google.protobuf.Api.name]" + // will be accepted. For example, if no audiences are in the setting, + // LibraryService API will only accept JWTs with the following audience + // "https://library-example.googleapis.com/google.example.library.v1.LibraryService". + // + // Example: + // + // audiences: bookstore_android.apps.googleusercontent.com, + // bookstore_web.apps.googleusercontent.com + string audiences = 2; +} \ No newline at end of file diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/http.proto b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/http.proto new file mode 100644 index 0000000..d554871 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/http.proto @@ -0,0 +1,377 @@ +// 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 +// +// 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. +// + +syntax = "proto3"; + +package google.api; + +option csharp_namespace = "Google.Protobuf"; +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; +option java_multiple_files = true; +option java_outer_classname = "HttpProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Defines the HTTP configuration for an API service. It contains a list of +// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method +// to one or more HTTP REST API methods. +message Http { + // A list of HTTP configuration rules that apply to individual API methods. + // + // **NOTE:** All service configuration rules follow "last one wins" order. + repeated HttpRule rules = 1; + + // When set to true, URL path parameters will be fully URI-decoded except in + // cases of single segment matches in reserved expansion, where "%2F" will be + // left encoded. + // + // The default behavior is to not decode RFC 6570 reserved characters in multi + // segment matches. + bool fully_decode_reserved_expansion = 2; +} + +// # gRPC Transcoding +// +// gRPC Transcoding is a feature for mapping between a gRPC method and one or +// more HTTP REST endpoints. It allows developers to build a single API service +// that supports both gRPC APIs and REST APIs. Many systems, including [Google +// APIs](https://github.com/googleapis/googleapis), +// [Cloud Endpoints](https://cloud.google.com/endpoints), [gRPC +// Gateway](https://github.com/grpc-ecosystem/grpc-gateway), +// and [Envoy](https://github.com/envoyproxy/envoy) proxy support this feature +// and use it for large scale production services. +// +// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies +// how different portions of the gRPC request message are mapped to the URL +// path, URL query parameters, and HTTP request body. It also controls how the +// gRPC response message is mapped to the HTTP response body. `HttpRule` is +// typically specified as an `google.api.http` annotation on the gRPC method. +// +// Each mapping specifies a URL path template and an HTTP method. The path +// template may refer to one or more fields in the gRPC request message, as long +// as each field is a non-repeated field with a primitive (non-message) type. +// The path template controls how fields of the request message are mapped to +// the URL path. +// +// Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/{name=messages/*}" +// }; +// } +// } +// message GetMessageRequest { +// string name = 1; // Mapped to URL path. +// } +// message Message { +// string text = 1; // The resource content. +// } +// +// This enables an HTTP REST to gRPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(name: "messages/123456")` +// +// Any fields in the request message which are not bound by the path template +// automatically become HTTP query parameters if there is no HTTP request body. +// For example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get:"/v1/messages/{message_id}" +// }; +// } +// } +// message GetMessageRequest { +// message SubMessage { +// string subfield = 1; +// } +// string message_id = 1; // Mapped to URL path. +// int64 revision = 2; // Mapped to URL query parameter `revision`. +// SubMessage sub = 3; // Mapped to URL query parameter `sub.subfield`. +// } +// +// This enables a HTTP JSON to RPC mapping as below: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | +// `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: +// "foo"))` +// +// Note that fields which are mapped to URL query parameters must have a +// primitive type or a repeated primitive type or a non-repeated message type. +// In the case of a repeated type, the parameter can be repeated in the URL +// as `...?param=A¶m=B`. In the case of a message type, each field of the +// message is mapped to a separate parameter, such as +// `...?foo.a=A&foo.b=B&foo.c=C`. +// +// For HTTP methods that allow a request body, the `body` field +// specifies the mapping. Consider a REST update method on the +// message resource collection: +// +// service Messaging { +// rpc UpdateMessage(UpdateMessageRequest) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "message" +// }; +// } +// } +// message UpdateMessageRequest { +// string message_id = 1; // mapped to the URL +// Message message = 2; // mapped to the body +// } +// +// The following HTTP JSON to RPC mapping is enabled, where the +// representation of the JSON in the request body is determined by +// protos JSON encoding: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" message { text: "Hi!" })` +// +// The special name `*` can be used in the body mapping to define that +// every field not bound by the path template should be mapped to the +// request body. This enables the following alternative definition of +// the update method: +// +// service Messaging { +// rpc UpdateMessage(Message) returns (Message) { +// option (google.api.http) = { +// patch: "/v1/messages/{message_id}" +// body: "*" +// }; +// } +// } +// message Message { +// string message_id = 1; +// string text = 2; +// } +// +// +// The following HTTP JSON to RPC mapping is enabled: +// +// HTTP | gRPC +// -----|----- +// `PATCH /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: +// "123456" text: "Hi!")` +// +// Note that when using `*` in the body mapping, it is not possible to +// have HTTP parameters, as all fields not bound by the path end in +// the body. This makes this option more rarely used in practice when +// defining REST APIs. The common usage of `*` is in custom methods +// which don't use the URL at all for transferring data. +// +// It is possible to define multiple HTTP methods for one RPC by using +// the `additional_bindings` option. Example: +// +// service Messaging { +// rpc GetMessage(GetMessageRequest) returns (Message) { +// option (google.api.http) = { +// get: "/v1/messages/{message_id}" +// additional_bindings { +// get: "/v1/users/{user_id}/messages/{message_id}" +// } +// }; +// } +// } +// message GetMessageRequest { +// string message_id = 1; +// string user_id = 2; +// } +// +// This enables the following two alternative HTTP JSON to RPC mappings: +// +// HTTP | gRPC +// -----|----- +// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` +// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: +// "123456")` +// +// ## Rules for HTTP mapping +// +// 1. Leaf request fields (recursive expansion nested messages in the request +// message) are classified into three categories: +// - Fields referred by the path template. They are passed via the URL path. +// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They are passed via the HTTP +// request body. +// - All other fields are passed via the URL query parameters, and the +// parameter name is the field path in the request message. A repeated +// field can be represented as multiple query parameters under the same +// name. +// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL query parameter, all fields +// are passed via URL path and HTTP request body. +// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP request body, all +// fields are passed via URL path and URL query parameters. +// +// ### Path template syntax +// +// Template = "/" Segments [ Verb ] ; +// Segments = Segment { "/" Segment } ; +// Segment = "*" | "**" | LITERAL | Variable ; +// Variable = "{" FieldPath [ "=" Segments ] "}" ; +// FieldPath = IDENT { "." IDENT } ; +// Verb = ":" LITERAL ; +// +// The syntax `*` matches a single URL path segment. The syntax `**` matches +// zero or more URL path segments, which must be the last part of the URL path +// except the `Verb`. +// +// The syntax `Variable` matches part of the URL path as specified by its +// template. A variable template must not contain other variables. If a variable +// matches a single path segment, its template may be omitted, e.g. `{var}` +// is equivalent to `{var=*}`. +// +// The syntax `LITERAL` matches literal text in the URL path. If the `LITERAL` +// contains any reserved character, such characters should be percent-encoded +// before the matching. +// +// If a variable contains exactly one path segment, such as `"{var}"` or +// `"{var=*}"`, when such a variable is expanded into a URL path on the client +// side, all characters except `[-_.~0-9a-zA-Z]` are percent-encoded. The +// server side does the reverse decoding. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{var}`. +// +// If a variable contains multiple path segments, such as `"{var=foo/*}"` +// or `"{var=**}"`, when such a variable is expanded into a URL path on the +// client side, all characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. +// The server side does the reverse decoding, except "%2F" and "%2f" are left +// unchanged. Such variables show up in the +// [Discovery +// Document](https://developers.google.com/discovery/v1/reference/apis) as +// `{+var}`. +// +// ## Using gRPC API Service Configuration +// +// gRPC API Service Configuration (service config) is a configuration language +// for configuring a gRPC service to become a user-facing product. The +// service config is simply the YAML representation of the `google.api.Service` +// proto message. +// +// As an alternative to annotating your proto file, you can configure gRPC +// transcoding in your service config YAML files. You do this by specifying a +// `HttpRule` that maps the gRPC method to a REST endpoint, achieving the same +// effect as the proto annotation. This can be particularly useful if you +// have a proto that is reused in multiple services. Note that any transcoding +// specified in the service config will override any matching transcoding +// configuration in the proto. +// +// Example: +// +// http: +// rules: +// # Selects a gRPC method and applies HttpRule to it. +// - selector: example.v1.Messaging.GetMessage +// get: /v1/messages/{message_id}/{sub.subfield} +// +// ## Special notes +// +// When gRPC Transcoding is used to map a gRPC to JSON REST endpoints, the +// proto to JSON conversion must follow the [proto3 +// specification](https://developers.google.com/protocol-buffers/docs/proto3#json). +// +// While the single segment variable follows the semantics of +// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 Simple String +// Expansion, the multi segment variable **does not** follow RFC 6570 Section +// 3.2.3 Reserved Expansion. The reason is that the Reserved Expansion +// does not expand special characters like `?` and `#`, which would lead +// to invalid URLs. As the result, gRPC Transcoding uses a custom encoding +// for multi segment variables. +// +// The path variables **must not** refer to any repeated or mapped field, +// because client libraries are not capable of handling such variable expansion. +// +// The path variables **must not** capture the leading "/" character. The reason +// is that the most common use case "{var}" does not capture the leading "/" +// character. For consistency, all path variables must share the same behavior. +// +// Repeated message fields must not be mapped to URL query parameters, because +// no client library can support such complicated mapping. +// +// If an API needs to use a JSON array for request or response body, it can map +// the request or response body to a repeated field. However, some gRPC +// Transcoding implementations may not support this feature. +message HttpRule { + // Selects a method to which this rule applies. + // + // Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + string selector = 1; + + // Determines the URL pattern is matched by this rules. This pattern can be + // used with any of the {get|put|post|delete|patch} methods. A custom method + // can be defined using the 'custom' field. + oneof pattern { + // Maps to HTTP GET. Used for listing and getting information about + // resources. + string get = 2; + + // Maps to HTTP PUT. Used for replacing a resource. + string put = 3; + + // Maps to HTTP POST. Used for creating a resource or performing an action. + string post = 4; + + // Maps to HTTP DELETE. Used for deleting a resource. + string delete = 5; + + // Maps to HTTP PATCH. Used for updating a resource. + string patch = 6; + + // The custom pattern is used for specifying an HTTP method that is not + // included in the `pattern` field, such as HEAD, or "*" to leave the + // HTTP method unspecified for this rule. The wild-card rule is useful + // for services that provide content to Web (HTML) clients. + CustomHttpPattern custom = 8; + } + + // The name of the request field whose value is mapped to the HTTP request + // body, or `*` for mapping all request fields not captured by the path + // pattern to the HTTP body, or omitted for not having any HTTP request body. + // + // NOTE: the referred field must be present at the top-level of the request + // message type. + string body = 7; + + // Optional. The name of the response field whose value is mapped to the HTTP + // response body. When omitted, the entire response message will be used + // as the HTTP response body. + // + // NOTE: The referred field must be present at the top-level of the response + // message type. + string response_body = 12; + + // Additional HTTP bindings for the selector. Nested bindings must + // not contain an `additional_bindings` field themselves (that is, + // the nesting may only be one level deep). + repeated HttpRule additional_bindings = 11; +} + +// A custom pattern is used for defining custom HTTP verb. +message CustomHttpPattern { + // The name of this custom HTTP verb. + string kind = 1; + + // The path matched by this custom verb. + string path = 2; +} diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/httpbody.proto b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/httpbody.proto new file mode 100644 index 0000000..bc5ea44 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/httpbody.proto @@ -0,0 +1,77 @@ +// Copyright 2020 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 +// +// 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. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/any.proto"; + +option cc_enable_arenas = true; +option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody"; +option java_multiple_files = true; +option java_outer_classname = "HttpBodyProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Message that represents an arbitrary HTTP body. It should only be used for +// payload formats that can't be represented as JSON, such as raw binary or +// an HTML page. +// +// +// This message can be used both in streaming and non-streaming API methods in +// the request as well as the response. +// +// It can be used as a top-level request field, which is convenient if one +// wants to extract parameters from either the URL or HTTP template into the +// request fields and also want access to the raw HTTP body. +// +// Example: +// +// message GetResourceRequest { +// // A unique request id. +// string request_id = 1; +// +// // The raw HTTP body is bound to this field. +// google.api.HttpBody http_body = 2; +// } +// +// service ResourceService { +// rpc GetResource(GetResourceRequest) returns (google.api.HttpBody); +// rpc UpdateResource(google.api.HttpBody) returns +// (google.protobuf.Empty); +// } +// +// Example with streaming methods: +// +// service CaldavService { +// rpc GetCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// rpc UpdateCalendar(stream google.api.HttpBody) +// returns (stream google.api.HttpBody); +// } +// +// Use of this type only changes how the request and response bodies are +// handled, all other features will continue to work unchanged. +message HttpBody { + // The HTTP Content-Type header value specifying the content type of the body. + string content_type = 1; + + // The HTTP request/response body as raw binary. + bytes data = 2; + + // Application specific response metadata. Must be set in the first response + // for streaming APIs. + repeated google.protobuf.Any extensions = 3; +} \ No newline at end of file diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/source_info.proto b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/source_info.proto new file mode 100644 index 0000000..e49658b --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/frontend/google/api/source_info.proto @@ -0,0 +1,31 @@ +// Copyright 2020 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 +// +// 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. + +syntax = "proto3"; + +package google.api; + +import "google/protobuf/any.proto"; + +option go_package = "google.golang.org/genproto/googleapis/api/serviceconfig;serviceconfig"; +option java_multiple_files = true; +option java_outer_classname = "SourceInfoProto"; +option java_package = "com.google.api"; +option objc_class_prefix = "GAPI"; + +// Source information used to create a Service Config +message SourceInfo { + // All files used during config generation. + repeated google.protobuf.Any source_files = 1; +} \ No newline at end of file diff --git a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/action.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/action.proto similarity index 87% rename from apps/cloudstate_protocol/priv/protos/protocol/cloudstate/action.proto rename to apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/action.proto index 3e0e173..b553e23 100644 --- a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/action.proto +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/action.proto @@ -1,30 +1,17 @@ -// Copyright 2019 Lightbend Inc. -// -// 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. // gRPC interface for Cloudstate Actions. syntax = "proto3"; -package cloudstate.action; +package eigr.functions.protocol.action; // Any is used so that domain events defined according to the action's business domain can be embedded inside // the protocol. import "google/protobuf/any.proto"; -import "cloudstate/entity.proto"; +import "entity.proto"; -option java_package = "io.cloudstate.protocol"; -option go_package = "github.com/cloudstateio/go-support/cloudstate/entity;entity"; +option java_package = "io.eigr.functions.protocol"; +option go_package = "github.com/eigr/go-support/eigr/entity;entity"; // An action command. // diff --git a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/crdt.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/crdt.proto similarity index 94% rename from apps/cloudstate_protocol/priv/protos/protocol/cloudstate/crdt.proto rename to apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/crdt.proto index 5c8135d..534444f 100644 --- a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/crdt.proto +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/crdt.proto @@ -16,15 +16,15 @@ syntax = "proto3"; -package cloudstate.crdt; +package eigr.functions.protocol.crdt; // Any is used so that domain events defined according to the functions business domain can be embedded inside // the protocol. import "google/protobuf/any.proto"; -import "cloudstate/entity.proto"; +import "protocol/entity.proto"; -option java_package = "io.cloudstate.protocol"; -option go_package = "cloudstate/protocol"; +option java_package = "io.eigr.functions.protocol"; +option go_package = "github.com/eigr/go-support/eigr/protocol;protocol"; // CRDT Protocol // @@ -85,10 +85,10 @@ message CrdtStreamIn { CrdtDelete deleted = 4; // A command, may be sent at any time. - Command command = 5; + eigr.functions.protocol.Command command = 5; // A stream has been cancelled. - StreamCancelled stream_cancelled = 6; + eigr.functions.protocol.StreamCancelled stream_cancelled = 6; } } @@ -102,7 +102,7 @@ message CrdtStreamOut { // A stream cancelled response, may be sent in response to stream_cancelled. CrdtStreamCancelledResponse stream_cancelled_response = 3; // A failure. Either sent in response to a command, or sent if some other error occurs. - Failure failure = 4; + eigr.functions.protocol.Failure failure = 4; } } @@ -315,9 +315,9 @@ message CrdtReply { int64 command_id = 1; - ClientAction client_action = 2; + eigr.functions.protocol.ClientAction client_action = 2; - repeated SideEffect side_effects = 4; + repeated eigr.functions.protocol.SideEffect side_effects = 4; CrdtStateAction state_action = 5; @@ -343,9 +343,9 @@ message CrdtStreamedMessage { int64 command_id = 1; - ClientAction client_action = 2; + eigr.functions.protocol.ClientAction client_action = 2; - repeated SideEffect side_effects = 3; + repeated eigr.functions.protocol.SideEffect side_effects = 3; // Indicates the stream should end, no messages may be sent for this command after this. bool end_stream = 4; @@ -354,7 +354,7 @@ message CrdtStreamedMessage { message CrdtStreamCancelledResponse { int64 command_id = 1; - repeated SideEffect side_effects = 2; + repeated eigr.functions.protocol.SideEffect side_effects = 2; CrdtStateAction state_action = 3; } diff --git a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/entity.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/entity.proto similarity index 97% rename from apps/cloudstate_protocol/priv/protos/protocol/cloudstate/entity.proto rename to apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/entity.proto index fa7faca..feee465 100644 --- a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/entity.proto +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/entity.proto @@ -16,7 +16,7 @@ syntax = "proto3"; -package cloudstate; +package eigr.functions.protocol; // Any is used so that domain events defined according to the functions business domain can be embedded inside // the protocol. @@ -24,8 +24,8 @@ import "google/protobuf/any.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/descriptor.proto"; -option java_package = "io.cloudstate.protocol"; -option go_package = "github.com/cloudstateio/go-support/cloudstate/protocol;protocol"; +option java_package = "io.eigr.functions.protocol"; +option go_package = "github.com/eigr/go-support/eigr/protocol;protocol"; // Transport-specific metadata associated with a message. // @@ -108,7 +108,7 @@ message Reply { // // If the metadata is ignored, the Cloudstate proxy MAY notify the user function by sending an error message to the // EntityDiscovery.ReportError gRPC call. - cloudstate.Metadata metadata = 2; + eigr.functions.protocol.Metadata metadata = 2; } // Forwards handling of this request to another entity. @@ -158,6 +158,9 @@ message SideEffect { // sent, or not. bool synchronous = 4; + // Send side effect to all entities of the given type. + bool broadcast = 6; + // The metadata to include with the side effect Metadata metadata = 5; } diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/entity_key.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/entity_key.proto new file mode 100644 index 0000000..cade3f5 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/entity_key.proto @@ -0,0 +1,30 @@ +// Copyright 2019 Lightbend Inc. +// +// 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. + +// Extension for specifying which field in a message is to be considered an +// entity key, for the purposes associating gRPC calls with entities and +// sharding. + +syntax = "proto3"; + +import "google/protobuf/descriptor.proto"; + +package eigr.functions.protocol; + +option java_package = "io.eigr.functions.protocol"; +option go_package = "github.com/cloudstateio/go-support/eigr;eigr"; + +extend google.protobuf.FieldOptions { + bool entity_key = 1080; +} \ No newline at end of file diff --git a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/event_sourced.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/event_sourced.proto similarity index 95% rename from apps/cloudstate_protocol/priv/protos/protocol/cloudstate/event_sourced.proto rename to apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/event_sourced.proto index 0417f14..e508467 100644 --- a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/event_sourced.proto +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/event_sourced.proto @@ -16,15 +16,15 @@ syntax = "proto3"; -package cloudstate.eventsourced; +package eigr.functions.protocol.eventsourced; // Any is used so that domain events defined according to the functions business domain can be embedded inside // the protocol. import "google/protobuf/any.proto"; -import "cloudstate/entity.proto"; +import "entity.proto"; -option java_package = "io.cloudstate.protocol"; -option go_package = "cloudstate/protocol"; +option java_package = "io.eigr.functions.protocol"; +option go_package = "eigr/protocol"; // The init message. This will always be the first message sent to the entity when // it is loaded. diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/eventing.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/eventing.proto new file mode 100644 index 0000000..9fef9a0 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/eventing.proto @@ -0,0 +1,76 @@ +// Copyright 2019 Lightbend Inc. +// +// 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. + +// Extension for specifying which topics a gRPC endpoint should be connected +// to, in order to facilitate consuming and producing events from a message broker. + +syntax = "proto3"; + +import "google/protobuf/descriptor.proto"; + +package eigr.functions.protocol.eventing; + +option java_package = "io.eigr.functions.protocol"; +option java_multiple_files = true; +option java_outer_classname = "EventsProto"; +option go_package = "github.com/eigr/go-support/eigr;eigr"; + +// Eventing configuration for a gRPC method. +message Eventing { + // The event source in configuration. + EventSource in = 1; + + // The event destination out configuration. + // + // Optional, if unset, messages out will not be published anywhere. + EventDestination out = 2; +} + +// Event source configuration +message EventSource { + + // The consumer group id. + // + // By default, all rpc methods on a given service with the same source will be part of the same virtual consumer + // group, messages will be routed to the different methods by type. This can be used to override that, if you want + // multiple methods to act as independent consumers of the same source (ie, if you want the same event to be + // published to each consumer) then give each consumer a unique name. + // + // Note that this does depend on the event source supporting multiple consumer groups. Queue based event sources + // may not support this. + string consumer_group = 1; + + oneof source { + + // A topic source. + // + // This will consume events from the given topic name. + string topic = 2; + + // An event log source. + // + // This will consume events from the given event log with the given persistence id. + string event_log = 3; + } +} + +message EventDestination { + oneof destination { + string topic = 1; + } +} + +extend google.protobuf.MethodOptions { + Eventing eventing = 1081; +} \ No newline at end of file diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/invoker.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/invoker.proto new file mode 100644 index 0000000..6c9ef94 --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/invoker.proto @@ -0,0 +1,55 @@ +// gRPC interface for invokable services. + +syntax = "proto3"; + +package eigr.functions.protocol; + +import "google/protobuf/any.proto"; +import "entity.proto"; + +option java_package = "io.eigr.functions.protocol"; +option go_package = "github.com/eigr/go-support/eigr/protocol;protocol"; + +message Error { + string message = 1; +} + +message Request { + // The name of the service to forward to. + string service_name = 1; + + // The name of the command. + string command_name = 2; + + // The payload. + google.protobuf.Any payload = 3; + + // The metadata to include with the forward + Metadata metadata = 4; + +} + +// The response sent by the remote service to the caller. +message Response { + + // An entity might return some useful information or it might return an error. + oneof result { + // The result of the function call. + google.protobuf.Any payload = 1; + + // The error returned by the remote service. + Error error = 2; + } + + // Metadata for the reply + Metadata metadata = 3; + +} + +// Invocation service. +service ServiceInvoker { + + // Send something to another entity and wait for their response. + rpc Invoke(Request) returns (Response) {} + +} \ No newline at end of file diff --git a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/value_entity.proto b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/value_entity.proto similarity index 94% rename from apps/cloudstate_protocol/priv/protos/protocol/cloudstate/value_entity.proto rename to apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/value_entity.proto index 109721c..a4fabc4 100644 --- a/apps/cloudstate_protocol/priv/protos/protocol/cloudstate/value_entity.proto +++ b/apps/eigr_protocol/priv/protos/eigr/functions/protocol/eigr/value_entity.proto @@ -16,15 +16,15 @@ syntax = "proto3"; -package cloudstate.valueentity; +package eigr.functions.protocol.valueentity; // Any is used so that domain events defined according to the functions business domain can be embedded inside // the protocol. import "google/protobuf/any.proto"; -import "cloudstate/entity.proto"; +import "entity.proto"; -option java_package = "io.cloudstate.protocol"; -option go_package = "github.com/cloudstateio/go-support/cloudstate/entity;entity"; +option java_package = "io.eigr.functions.protocol"; +option go_package = "github.com/eigr/go-support/eigr/entity;entity"; // The Value Entity service service ValueEntity { diff --git a/apps/eigr_protocol/priv/protos/eigr/functions/proxy/grpc/reflection/v1alpha/reflection.proto b/apps/eigr_protocol/priv/protos/eigr/functions/proxy/grpc/reflection/v1alpha/reflection.proto new file mode 100644 index 0000000..462e85a --- /dev/null +++ b/apps/eigr_protocol/priv/protos/eigr/functions/proxy/grpc/reflection/v1alpha/reflection.proto @@ -0,0 +1,136 @@ +// Copyright 2016 gRPC authors. +// +// 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. + +// Service exported by server reflection + +syntax = "proto3"; + +package grpc.reflection.v1alpha; + +service ServerReflection { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + rpc ServerReflectionInfo(stream ServerReflectionRequest) + returns (stream ServerReflectionResponse); +} + +// The message sent by the client when calling ServerReflectionInfo method. +message ServerReflectionRequest { + string host = 1; + // To use reflection service, the client should set one of the following + // fields in message_request. The server distinguishes requests by their + // defined field and then handles them using corresponding methods. + oneof message_request { + // Find a proto file by the file name. + string file_by_filename = 3; + + // Find the proto file that declares the given fully-qualified symbol name. + // This field should be a fully-qualified symbol name + // (e.g. .[.] or .). + string file_containing_symbol = 4; + + // Find the proto file which defines an extension extending the given + // message type with the given field number. + ExtensionRequest file_containing_extension = 5; + + // Finds the tag numbers used by all known extensions of the given message + // type, and appends them to ExtensionNumberResponse in an undefined order. + // Its corresponding method is best-effort: it's not guaranteed that the + // reflection service will implement this method, and it's not guaranteed + // that this method will provide all extensions. Returns + // StatusCode::UNIMPLEMENTED if it's not implemented. + // This field should be a fully-qualified type name. The format is + // . + string all_extension_numbers_of_type = 6; + + // List the full names of registered services. The content will not be + // checked. + string list_services = 7; + } +} + +// The type name and extension number sent by the client when requesting +// file_containing_extension. +message ExtensionRequest { + // Fully-qualified type name. The format should be . + string containing_type = 1; + int32 extension_number = 2; +} + +// The message sent by the server to answer ServerReflectionInfo method. +message ServerReflectionResponse { + string valid_host = 1; + ServerReflectionRequest original_request = 2; + // The server set one of the following fields accroding to the message_request + // in the request. + oneof message_response { + // This message is used to answer file_by_filename, file_containing_symbol, + // file_containing_extension requests with transitive dependencies. As + // the repeated label is not allowed in oneof fields, we use a + // FileDescriptorResponse message to encapsulate the repeated fields. + // The reflection service is allowed to avoid sending FileDescriptorProtos + // that were previously sent in response to earlier requests in the stream. + FileDescriptorResponse file_descriptor_response = 4; + + // This message is used to answer all_extension_numbers_of_type requst. + ExtensionNumberResponse all_extension_numbers_response = 5; + + // This message is used to answer list_services request. + ListServiceResponse list_services_response = 6; + + // This message is used when an error occurs. + ErrorResponse error_response = 7; + } +} + +// Serialized FileDescriptorProto messages sent by the server answering +// a file_by_filename, file_containing_symbol, or file_containing_extension +// request. +message FileDescriptorResponse { + // Serialized FileDescriptorProto messages. We avoid taking a dependency on + // descriptor.proto, which uses proto2 only features, by making them opaque + // bytes instead. + repeated bytes file_descriptor_proto = 1; +} + +// A list of extension numbers sent by the server answering +// all_extension_numbers_of_type request. +message ExtensionNumberResponse { + // Full name of the base type, including the package name. The format + // is . + string base_type_name = 1; + repeated int32 extension_number = 2; +} + +// A list of ServiceResponse sent by the server answering list_services request. +message ListServiceResponse { + // The information of each service may be expanded in the future, so we use + // ServiceResponse message to encapsulate it. + repeated ServiceResponse service = 1; +} + +// The information of a single service used by ListServiceResponse to answer +// list_services request. +message ServiceResponse { + // Full name of a registered service, including its package name. The format + // is . + string name = 1; +} + +// The error code and error message sent by the server when an error occurs. +message ErrorResponse { + // This field uses the error codes defined in grpc::StatusCode. + int32 error_code = 1; + string error_message = 2; +} \ No newline at end of file diff --git a/apps/eigr_protocol/test/eigr_protocol_test.exs b/apps/eigr_protocol/test/eigr_protocol_test.exs new file mode 100644 index 0000000..a62da0a --- /dev/null +++ b/apps/eigr_protocol/test/eigr_protocol_test.exs @@ -0,0 +1,8 @@ +defmodule EigrProtocolTest do + use ExUnit.Case + doctest EigrProtocol + + test "greets the world" do + assert EigrProtocol.hello() == :world + end +end diff --git a/apps/eigr_protocol/test/test_helper.exs b/apps/eigr_protocol/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/apps/eigr_protocol/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/apps/eventing/.formatter.exs b/apps/eventing/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/apps/eventing/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/apps/eventing/.gitignore b/apps/eventing/.gitignore new file mode 100644 index 0000000..7c1ff53 --- /dev/null +++ b/apps/eventing/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +eventing-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/apps/eventing/README.md b/apps/eventing/README.md new file mode 100644 index 0000000..dcc6f81 --- /dev/null +++ b/apps/eventing/README.md @@ -0,0 +1,21 @@ +# Eventing + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `eventing` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:eventing, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/apps/eventing/lib/eventing.ex b/apps/eventing/lib/eventing.ex new file mode 100644 index 0000000..2f2307d --- /dev/null +++ b/apps/eventing/lib/eventing.ex @@ -0,0 +1,18 @@ +defmodule Eventing do + @moduledoc """ + Documentation for `Eventing`. + """ + + @doc """ + Hello world. + + ## Examples + + iex> Eventing.hello() + :world + + """ + def hello do + :world + end +end diff --git a/apps/eventing/mix.exs b/apps/eventing/mix.exs new file mode 100644 index 0000000..4b6ea3d --- /dev/null +++ b/apps/eventing/mix.exs @@ -0,0 +1,31 @@ +defmodule Eventing.MixProject do + use Mix.Project + + def project do + [ + app: :eventing, + version: "0.1.0", + build_path: "../../_build", + config_path: "../../config/config.exs", + deps_path: "../../deps", + lockfile: "../../mix.lock", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:cloudevents, "~> 0.4.0"} + ] + end +end diff --git a/apps/eventing/test/eventing_test.exs b/apps/eventing/test/eventing_test.exs new file mode 100644 index 0000000..d8cf404 --- /dev/null +++ b/apps/eventing/test/eventing_test.exs @@ -0,0 +1,8 @@ +defmodule EventingTest do + use ExUnit.Case + doctest Eventing + + test "greets the world" do + assert Eventing.hello() == :world + end +end diff --git a/apps/eventing/test/test_helper.exs b/apps/eventing/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/apps/eventing/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/apps/massa_proxy/lib/massa_proxy/protocol/router.ex b/apps/massa_proxy/lib/massa_proxy/protocol/router.ex deleted file mode 100644 index 7745029..0000000 --- a/apps/massa_proxy/lib/massa_proxy/protocol/router.ex +++ /dev/null @@ -1,37 +0,0 @@ -defmodule MassaProxy.Protocol.Router do - @doc """ - Dispatch the given `mod`, `fun`, `args` request - to the appropriate node based on the `bucket`. - """ - def route(bucket, mod, fun, args) do - # Get the first byte of the binary - first = :binary.first(bucket) - - # Try to find an entry in the table() or raise - entry = - Enum.find(table(), fn {enum, _node} -> - first in enum - end) || no_entry_error(bucket) - - # If the entry node is the current node - if elem(entry, 1) == node() do - apply(mod, fun, args) - else - {KV.RouterTasks, elem(entry, 1)} - |> Task.Supervisor.async(KV.Router, :route, [bucket, mod, fun, args]) - |> Task.await() - end - end - - defp no_entry_error(bucket) do - raise "could not find entry for #{inspect(bucket)} in table #{inspect(table())}" - end - - @doc """ - The routing table. - """ - def table do - # Replace computer-name with your local machine name - [{?a..?m, :"foo@computer-name"}, {?n..?z, :"bar@computer-name"}] - end -end diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/dispatcher.ex b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/dispatcher.ex index 59d6f2d..750ef81 100644 --- a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/dispatcher.ex +++ b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/dispatcher.ex @@ -5,6 +5,7 @@ defmodule MassaProxy.Runtime.Grpc.Server.Dispatcher do require Logger alias MassaProxy.Runtime.Grpc.Protocol.Action.Handler, as: ActionHandler alias MassaProxy.Runtime.Grpc.Protocol.EventSourced.Handler, as: EventSourcedHandler + alias MassaProxy.Runtime.MiddlewareSupervisor def dispatch( %{ @@ -22,10 +23,16 @@ defmodule MassaProxy.Runtime.Grpc.Server.Dispatcher do "Handle stream: #{inspect(stream)}. With persistence id: #{inspect(persistence_id)}" ) - case entity_type do - "cloudstate.action.ActionProtocol" -> ActionHandler.handle(payload) - "cloudstate.eventsourced.EventSourced" -> EventSourcedHandler.handle(payload) - _ -> Logger.error("Not Implemented Entity type #{entity_type}") + with {:ok, pid} <- MiddlewareSupervisor.start_middleware(payload) do + Logger.debug("Started middleware with pid: #{inspect(pid)}") + + case entity_type do + "cloudstate.action.ActionProtocol" -> ActionHandler.handle(payload) + "cloudstate.eventsourced.EventSourced" -> EventSourcedHandler.handle(payload) + _ -> Logger.error("Not Implemented Entity type #{entity_type}") + end + else + error -> Logger.error("Middleware error #{inspect(error)}") end end end diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/action_handler.ex b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/action_handler.ex index ad86385..d62ac71 100644 --- a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/action_handler.ex +++ b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/action_handler.ex @@ -5,20 +5,21 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Action.Handler do so it is necessary to identify in the payload the type of request that is arriving to decide how to forward messages via the protocol to the user's function """ - require Logger - alias MassaProxy.Runtime.Grpc.Protocol.Action.Unary.Handler, as: UnaryHandler alias MassaProxy.Runtime.Grpc.Protocol.Action.Stream.Handler, as: StreamHandler @behaviour MassaProxy.Protocol.Handler - @impl true - def handle(%{request_type: request_type} = payload) do - case request_type do - "unary" -> UnaryHandler.handle_unary(payload) - "stream_in" -> StreamHandler.handle_stream_in(payload) - "stream_out" -> StreamHandler.handle_stream_out(payload) - "streamed" -> StreamHandler.handle_streamed(payload) - end - end + @impl MassaProxy.Protocol.Handler + def handle(%{request_type: "unary"} = payload), + do: UnaryHandler.handle_unary(payload) + + def handle(%{request_type: "stream_in"} = payload), + do: StreamHandler.handle_stream_in(payload) + + def handle(%{request_type: "stream_out"} = payload), + do: StreamHandler.handle_stream_out(payload) + + def handle(%{request_type: "streamed"} = payload), + do: StreamHandler.handle_streamed(payload) end diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/protocol.ex b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/protocol.ex index cb7433c..ad23139 100644 --- a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/protocol.ex +++ b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/protocol.ex @@ -1,7 +1,9 @@ -defmodule MassaProxy.Runtime.Grpc.Protocol.Action.Protocol do +defmodule Runtime.GRPC.Protocol.Action.Protocol do + require Logger + alias Cloudstate.{Action.ActionCommand, Action.ActionResponse, Metadata} alias Google.Protobuf.Any - alias MassaProxy.Util + alias Runtime.Util @type t :: map() @type command_type :: :payload | :metadata | :full @@ -28,15 +30,34 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Action.Protocol do ) end - def build_msg(ctx, :payload) do - ActionCommand.new(payload: build_payload(ctx)) + def build_msg(%{service_name: service_name, original_method: original_method} = ctx, :payload) do + ActionCommand.new( + service_name: service_name, + name: original_method, + metadata: Metadata.new(), + payload: build_payload(ctx) + ) end @spec build_stream(t()) :: Enumerable.t() - def build_stream(%{message: msgs} = state) do + def build_stream( + %{service_name: service_name, original_method: original_method, message: msgs} = state + ) do + # The first message in will contain the request metadata, including the + # service name and command name. It will not have an associated payload set. + # This will be followed by zero to many messages in with a payload + init_command = [ + ActionCommand.new( + service_name: service_name, + name: original_method, + metadata: Metadata.new() + ) + ] + + init_command + |> Stream.concat(msgs) # Need to signal end_of_stream so attach a token to # end of the stream so that we can call `GRPC.Stub.end_stream` - msgs |> Stream.concat([:halt]) |> Stream.transform({:pre_send, state}, &transform/2) end @@ -56,12 +77,25 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Action.Protocol do {[command], acc} end - defp build_payload(%{input_type: input_type, message: msg}), + defp build_payload(%{input_type: input_type, message: msg}) when is_binary(input_type), do: msg + + defp build_payload(%{input_type: input_type, message: msg}) when is_atom(input_type), do: Any.new( type_url: Util.get_type_url(input_type), value: input_type.encode(msg) ) - defp decode_payload(output_mod, %{payload: %Any{value: bin}}), do: output_mod.decode(bin) + # defp decode_payload(output_mod, %{payload: %Any{value: bin}}) when is_binary(output_mod) do + # mod = + # Any.new( + # type_url: Util.get_type_url("type.googleapis.com/cloudstate.tck.model.action.Response"), + # value: bin + # ) + + # mod.decode(bin) + # end + + defp decode_payload(output_mod, %{payload: %Any{value: bin}}) when is_atom(output_mod), + do: output_mod.decode(bin) end diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/stream_handler.ex b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/stream_handler.ex index 390a158..af54a50 100644 --- a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/stream_handler.ex +++ b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/stream_handler.ex @@ -2,33 +2,42 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Action.Stream.Handler do @moduledoc """ This module is responsible for handling stream requests of the Action protocol """ + require Logger alias Cloudstate.Action.ActionProtocol.Stub, as: ActionClient + alias Google.Protobuf.Empty alias MassaProxy.Runtime.Grpc.Protocol.Action.Protocol, as: ActionProtocol + alias MassaProxy.Runtime.Middleware - import MassaProxy.Util, only: [get_connection: 0] + alias Runtime.Util def handle_streamed(%{stream: stream} = ctx) do - messages = ActionProtocol.build_stream(ctx) - - with {:ok, conn} <- get_connection(), - client_stream = ActionClient.handle_streamed(conn), - :ok <- client_stream |> run_stream(messages) |> Stream.run(), - {:ok, consumer_stream} <- GRPC.Stub.recv(client_stream) do + with messages <- ActionProtocol.build_stream(ctx), + {:ok, consumer_stream} <- Middleware.streamed(ctx, messages) do consumer_stream - |> Stream.each(fn {:ok, r} -> - GRPC.Server.send_reply(stream, ActionProtocol.decode(ctx, r)) + |> Stream.each(fn + {:ok, %Cloudstate.Action.ActionResponse{response: nil}} -> + GRPC.Server.send_reply(stream, Empty.new()) + + {:ok, %Cloudstate.Action.ActionResponse{response: _response} = r} -> + GRPC.Server.send_reply(stream, ActionProtocol.decode(ctx, r)) + + {:error, _reason} = err -> + Logger.error("Error while handling stream request: #{inspect(err)}") + err end) |> Stream.run() else - {:error, _reason} = err -> err + {:error, _reason} = err -> + Logger.error("Error while handling stream request: #{inspect(err)}") + err end end def handle_stream_in(ctx) do messages = ActionProtocol.build_stream(ctx) - with {:ok, conn} <- get_connection(), + with {:ok, conn} <- Util.get_connection(), client_stream = ActionClient.handle_streamed_in(conn), task_result <- run_stream(client_stream, messages), :ok <- accumlate_stream_result(task_result), @@ -42,7 +51,7 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Action.Stream.Handler do def handle_stream_out(%{stream: stream} = ctx) do message = ActionProtocol.build_msg(ctx, :full) - with {:ok, conn} <- get_connection(), + with {:ok, conn} <- Util.get_connection(), {:ok, client_stream} <- ActionClient.handle_streamed_out(conn, message, []) do Stream.each(client_stream, fn {:ok, response} -> GRPC.Server.send_reply(stream, ActionProtocol.decode(ctx, response)) diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/unary_handler.ex b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/unary_handler.ex index 9d64436..f471131 100644 --- a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/unary_handler.ex +++ b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/action/unary_handler.ex @@ -3,23 +3,19 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Action.Unary.Handler do This module is responsible for handling unary requests of the Action protocol """ require Logger - alias Cloudstate.Action.ActionProtocol.Stub, as: ActionClient alias MassaProxy.Runtime.Grpc.Protocol.Action.Protocol, as: ActionProtocol - - import MassaProxy.Util, only: [get_connection: 0] + alias MassaProxy.Runtime.Middleware def handle_unary(ctx) do - # Call user function and return - message = ActionProtocol.build_msg(ctx) - response = - with {:ok, channel} <- get_connection(), - {:ok, response} <- ActionClient.handle_unary(channel, message) do + with message <- ActionProtocol.build_msg(ctx), + {:ok, response} <- Middleware.unary(ctx, message) do ActionProtocol.decode(ctx, response) else {:error, reason} -> {:error, "Failure to make unary request #{inspect(reason)}"} end - Logger.debug(fn -> "User function response #{inspect(response)}" end) + + Logger.debug(fn -> "Unary.Handler User function response #{inspect(response)}" end) response end diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/discovery/manager.ex b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/discovery/manager.ex index 7e58ca3..958cb99 100644 --- a/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/discovery/manager.ex +++ b/apps/massa_proxy/lib/massa_proxy/runtime/grpc/protocol/discovery/manager.ex @@ -8,6 +8,7 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Discovery.Manager do alias MassaProxy.CloudstateEntity alias MassaProxy.Server.GrpcServer alias Google.Protobuf.FileDescriptorSet + alias Runtime.{Entity.EntityRegistry, Util} inject(MassaProxy.Infra.Config) @@ -77,12 +78,14 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Discovery.Manager do end defp register_entity(entity) do + Logger.debug("Registering entity #{inspect(entity)}") + case entity.entity_type do "cloudstate.eventsourced.EventSourced" -> - MassaProxy.Entity.EntityRegistry.register("EventSourced", [entity]) + EntityRegistry.register("EventSourced", [entity]) "cloudstate.action.ActionProtocol" -> - MassaProxy.Entity.EntityRegistry.register("Action", [entity]) + EntityRegistry.register("Action", [entity]) _ -> Logger.warn("Unknown Entity #{entity.entity_type}") @@ -171,7 +174,7 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Discovery.Manager do defp extract_field_attributes(field) do has_key = if field.options != nil do - opts = MassaProxy.Util.contains_key?(field) + opts = Util.contains_key?(field) Logger.debug("Has key?: #{inspect(opts)}") end @@ -193,7 +196,7 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Discovery.Manager do defp extract_service_method(method) do http_options = if method.options != nil do - http_rules = MassaProxy.Util.get_http_rule(method) + http_rules = Util.get_http_rule(method) Logger.debug("MehodOptions: #{inspect(http_rules)}") %{type: "http", data: http_rules} @@ -201,7 +204,7 @@ defmodule MassaProxy.Runtime.Grpc.Protocol.Discovery.Manager do eventing_options = if method.options != nil do - evt_rules = MassaProxy.Util.get_eventing_rule(method) + evt_rules = Util.get_eventing_rule(method) Logger.debug("MehodOptions: #{inspect(evt_rules)}") %{type: "eventing", data: evt_rules} diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/middleware.ex b/apps/massa_proxy/lib/massa_proxy/runtime/middleware.ex new file mode 100644 index 0000000..9a19ae2 --- /dev/null +++ b/apps/massa_proxy/lib/massa_proxy/runtime/middleware.ex @@ -0,0 +1,236 @@ +defmodule MassaProxy.Runtime.Middleware do + @moduledoc """ + Middleware is a module that can be used to add functionality + to interact with the user role and other remote middlewares. + """ + use GenServer + require Logger + + alias Cloudstate.{Action.ActionResponse, SideEffect} + alias Cloudstate.Action.ActionProtocol.Stub, as: ActionClient + alias Runtime.Protocol.Router + alias MassaProxy.Runtime.Grpc.Protocol.Action.Protocol, as: ActionProtocol + + alias Runtime.Util + + @impl true + def init(state) do + {:ok, state} + end + + def start_link(%{name: name} = state) do + GenServer.start_link(__MODULE__, state, name: name) + end + + @impl true + def handle_call( + {:handle_unary, %{context: context, payload: message} = _input}, + _from, + # %{command_processor: command_processor} = state + state + ) do + result = + with {:ok, channel} <- Util.get_connection(), + {:ok, %ActionResponse{side_effects: effects} = command} <- + ActionClient.handle_unary(channel, message), + {:ok, result} <- process_command(nil, context, command) do + call_effects(context, effects) + {:ok, result} + else + {:error, reason} -> {:error, "Failure to make unary request #{inspect(reason)}"} + end + + Logger.debug("Middleware User function response #{inspect(result)}") + + {:reply, result, state} + end + + @impl true + def handle_call( + {:handle_streamed, %{context: context, payload: messages} = _input}, + from, + state + ) do + spawn(fn -> + stream_result = + with {:ok, conn} <- Util.get_connection(), + client_stream = ActionClient.handle_streamed(conn), + :ok <- run_stream(client_stream, messages) |> Stream.run(), + {:ok, consumer_stream} <- GRPC.Stub.recv(client_stream) do + consumer_stream = + consumer_stream + |> Stream.map(fn + {:ok, %ActionResponse{side_effects: effects} = command} -> + Logger.debug("Consumer Stream result: #{inspect(command)}") + + result = + case process_command(nil, context, command) do + {:ok, result} -> + {:ok, result} + + {:error, reason} -> + {:error, "Failure on process command #{inspect(reason)}"} + end + + call_effects(context, effects) + result + + {:error, reason} -> + {:error, "Failure on process client stream #{inspect(reason)}"} + end) + |> Enum.to_list() + + {:ok, consumer_stream} + else + {:ok, []} -> + {:error, "Client not returned a stream"} + + {:error, reason} -> + {:error, reason} + end + + GenServer.reply(from, stream_result) + end) + + {:noreply, state} + end + + @impl true + def handle_cast({:handle_effect, ctx}, state) do + with message <- ActionProtocol.build_msg(ctx), + {:ok, channel} <- Util.get_connection(), + {:ok, %ActionResponse{} = commands} <- + ActionClient.handle_unary(channel, message), + {:ok, result} <- process_command(nil, ctx, commands) do + Logger.debug( + "Handle effects User function response #{inspect(commands)}. With commands result #{inspect(result)}" + ) + else + {:error, reason} -> + Logger.warn("Failure to make unary request #{inspect(reason)}") + end + + {:noreply, state} + end + + @impl true + def handle_info(msg, state) do + Logger.notice("Received unexpected message: #{inspect(msg)}") + + {:noreply, state} + end + + def unary(%{entity_type: entity_type} = ctx, message) do + GenServer.call(get_name(entity_type), {:handle_unary, %{context: ctx, payload: message}}) + end + + def streamed(%{entity_type: entity_type} = ctx, messages) do + GenServer.call(get_name(entity_type), {:handle_streamed, %{context: ctx, payload: messages}}) + end + + def effect(%{entity_type: entity_type} = ctx) do + GenServer.cast(get_name(entity_type), {:handle_effect, ctx}) + end + + defp process_command( + _command_processor, + _context, + %ActionResponse{response: {:reply, %Cloudstate.Reply{} = _reply}} = message + ) do + {:ok, message} + end + + defp process_command( + _command_processor, + _context, + %ActionResponse{response: {:failure, %Cloudstate.Failure{} = _failure}} = message + ) do + {:ok, message} + end + + defp process_command( + _command_processor, + _context, + %ActionResponse{response: {:forward, %Cloudstate.Forward{} = _forward}} = message + ) do + {:ok, message} + end + + defp process_command( + _command_processor, + _context, + %ActionResponse{response: nil} = _message + ) do + {:ok, %ActionResponse{}} + end + + defp process_command(nil, _context, message) do + {:ok, message} + end + + defp call_effects(_ctx, []), do: {:ok, []} + + defp call_effects( + %{entity_type: entity_type} = _ctx, + effects + ) + when is_list(effects) and length(effects) > 0 do + Enum.each(effects, fn %SideEffect{ + service_name: service_name, + command_name: command_name, + synchronous: synchronous, + payload: %Google.Protobuf.Any{type_url: input_type} = payload + } = effect -> + Logger.debug( + "Handling side effect #{inspect(effect)}} with command name: #{command_name} and input type: #{input_type}" + ) + + message = %{ + message: payload, + entity_type: nil, + service_name: nil, + request_type: nil, + original_method: nil, + input_type: nil, + output_type: nil, + persistence_id: nil, + stream: nil + } + + Router.route( + entity_type, + service_name, + command_name, + input_type, + !synchronous, + __MODULE__, + :effect, + message + ) + end) + end + + defp call_effects(_ctx, _), do: {:ok, []} + + defp get_name(entity_type) do + mod = + entity_type + |> String.split(".") + |> Enum.at(-1) + + Module.concat(__MODULE__, mod) + end + + defp run_stream(client_stream, messages) do + messages + |> Stream.map(&send_stream_msg(client_stream, &1)) + end + + defp send_stream_msg(client_stream, :halt) do + GRPC.Stub.end_stream(client_stream) + end + + defp send_stream_msg(client_stream, msg) do + GRPC.Stub.send_request(client_stream, msg, []) + end +end diff --git a/apps/massa_proxy/lib/massa_proxy/runtime/middleware_supervisor.ex b/apps/massa_proxy/lib/massa_proxy/runtime/middleware_supervisor.ex new file mode 100644 index 0000000..03e0082 --- /dev/null +++ b/apps/massa_proxy/lib/massa_proxy/runtime/middleware_supervisor.ex @@ -0,0 +1,39 @@ +defmodule MassaProxy.Runtime.MiddlewareSupervisor do + @moduledoc """ + Supervisor for the middleware stack. + """ + use DynamicSupervisor + + alias MassaProxy.Runtime.Middleware + + @impl true + def init(_opts), do: DynamicSupervisor.init(strategy: :one_for_one) + + @doc false + def start_link(_opts), + do: DynamicSupervisor.start_link(__MODULE__, [shutdown: 120_000], name: __MODULE__) + + def start_middleware(%{entity_type: entity_type} = state) do + process_name = get_name(entity_type) + + child_spec = %{ + id: process_name, + start: {Middleware, :start_link, [Map.put(state, :name, process_name)]}, + restart: :transient + } + + case DynamicSupervisor.start_child(__MODULE__, child_spec) do + {:error, {:already_started, pid}} -> {:ok, pid} + {:ok, pid} -> {:ok, pid} + end + end + + defp get_name(entity_type) do + mod = + entity_type + |> String.split(".") + |> Enum.at(-1) + + Module.concat(Middleware, mod) + end +end diff --git a/apps/massa_proxy/lib/massa_proxy/server/grpc_server.ex b/apps/massa_proxy/lib/massa_proxy/server/grpc_server.ex index 03f5645..db33485 100644 --- a/apps/massa_proxy/lib/massa_proxy/server/grpc_server.ex +++ b/apps/massa_proxy/lib/massa_proxy/server/grpc_server.ex @@ -4,6 +4,7 @@ defmodule MassaProxy.Server.GrpcServer do alias MassaProxy.{Util, Infra.Cache, Server.HttpRouter} alias MassaProxy.Infra.Cache.Distributed + alias Runtime.Util def start(descriptors, entities) do case Cache.get(:cached_servers, :grpc) do @@ -170,7 +171,10 @@ defmodule MassaProxy.Server.GrpcServer do entities |> Flow.from_enumerable() |> Flow.map( - &Enum.join([Util.normalize_service_name(&1.service_name), "Service.ProxyService"], ".") + &Enum.join( + [Util.normalize_service_name(&1.service_name), "Service.ProxyService"], + "." + ) ) |> Enum.to_list() @@ -250,18 +254,6 @@ defmodule MassaProxy.Server.GrpcServer do defp get_request_type(services), do: Enum.reduce(services.methods, %{}, fn method, acc -> - Map.put(acc, Util.normalize_method_name(method.name), get_type(method)) + Map.put(acc, Util.normalize_method_name(method.name), Util.get_type(method)) end) - - defp get_type(method) do - type = - cond do - method.unary == true -> "unary" - method.streamed == true -> "streamed" - method.stream_in == true -> "stream_in" - method.stream_out == true -> "stream_out" - end - - type - end end diff --git a/apps/massa_proxy/lib/massa_proxy/util.ex b/apps/massa_proxy/lib/massa_proxy/util.ex index e71b658..a0c7656 100644 --- a/apps/massa_proxy/lib/massa_proxy/util.ex +++ b/apps/massa_proxy/lib/massa_proxy/util.ex @@ -79,99 +79,6 @@ defmodule MassaProxy.Util do end end - def contains_key?(field_descriptor) do - Logger.debug("FieldOptions: #{inspect(field_descriptor)}") - - entity_key_ext = - Google.Protobuf.FieldOptions.get_extension( - field_descriptor.options, - Cloudstate.PbExtension, - :entity_key - ) - - Logger.debug("Entity key extension: #{inspect(entity_key_ext)}") - entity_key_ext - end - - def get_http_rule(method_descriptor) do - Logger.debug("MethodOptions HTTP Rules: #{inspect(method_descriptor)}") - - Google.Protobuf.MethodOptions.get_extension( - method_descriptor.options, - Google.Api.PbExtension, - :http - ) - end - - def get_eventing_rule(method_descriptor) do - Logger.debug("MethodOptions Eventing Rules: #{inspect(method_descriptor)}") - - evt_ext = - Google.Protobuf.MethodOptions.get_extension( - method_descriptor.options, - Cloudstate.PbExtension, - :eventing - ) - - Logger.debug("Eventing extension: #{inspect(evt_ext)}") - evt_ext - end - - def get_type_url(type) do - parts = - type - |> to_string - |> String.replace("Elixir.", "") - |> String.split(".") - - package_name = - with {_, list} <- parts |> List.pop_at(-1), - do: list |> Stream.map(&String.downcase(&1)) |> Enum.join(".") - - type_name = parts |> List.last() - "type.googleapis.com/#{package_name}.#{type_name}" - end - - def compile(file) do - Code.compile_string(file) - rescue - error in UndefinedFunctionError -> - Logger.error("Error in Module definition. Make sure the service name is correct") - raise error - - error -> - Logger.error("Error during Service compilation phase #{inspect(error)}") - end - - def normalize_service_name(name) do - name - |> String.split(".") - |> Stream.map(&Macro.camelize(&1)) - |> Enum.join(".") - end - - def normalize_method_name(name), do: Macro.underscore(name) - - def get_module(filename, bindings \\ []), do: EEx.eval_file(filename, bindings) - - def get_connection(), - do: GRPC.Stub.connect(get_address(is_uds_enable?()), interceptors: [GRPC.Logger.Client]) - - def get_uds_address(), - do: Application.get_env(:massa_proxy, :user_function_sock_addr, "/var/run/cloudstate.sock") - - def is_uds_enable?(), - do: Application.get_env(:massa_proxy, :user_function_uds_enable, false) - - defp get_function_host(), - do: Application.get_env(:massa_proxy, :user_function_host, "127.0.0.1") - - def get_function_port(), do: Application.get_env(:massa_proxy, :user_function_port, 8080) - - def get_address(false), do: "#{get_function_host()}:#{get_function_port()}" - - def get_address(true), do: "#{get_uds_address()}" - defp get_gossip_strategy(), do: [ proxy: [ diff --git a/apps/massa_proxy/lib/supervisor.ex b/apps/massa_proxy/lib/supervisor.ex index 081a5e0..6f915c5 100644 --- a/apps/massa_proxy/lib/supervisor.ex +++ b/apps/massa_proxy/lib/supervisor.ex @@ -2,6 +2,9 @@ defmodule MassaProxy.Children do @moduledoc false use Supervisor + alias Runtime + alias Runtime.{MiddlewareDefinition, State} + require Logger def start_link(config) do @@ -10,14 +13,21 @@ defmodule MassaProxy.Children do @impl true def init(config) do - children = [ + children = mount_supervisor_tree(config) + + Supervisor.init(children, strategy: :one_for_one) + end + + defp mount_supervisor_tree(config) do + [ http_server(config), - {Task.Supervisor, name: MassaProxy.TaskSupervisor}, {Registry, [name: MassaProxy.LocalRegistry, keys: :unique]}, {DynamicSupervisor, [name: MassaProxy.LocalSupervisor, strategy: :one_for_one]}, + {DynamicSupervisor, + [name: MassaProxy.Runtime.MiddlewareSupervisor, strategy: :one_for_one]}, {MassaProxy.Infra.Cache.Distributed, []}, + # {Runtime, %State{middlewares: [%MiddlewareDefinition{}]}} local_node(), - {MassaProxy.Entity.EntityRegistry.Supervisor, [%{}]}, %{ id: CachedServers, start: {MassaProxy.Infra.Cache, :start_link, [[cache_name: :cached_servers]]} @@ -27,8 +37,6 @@ defmodule MassaProxy.Children do start: {MassaProxy.Infra.Cache, :start_link, [[cache_name: :reflection_cache]]} } ] - - Supervisor.init(children, strategy: :one_for_one) end defp http_server(config) do diff --git a/apps/massa_proxy/mix.exs b/apps/massa_proxy/mix.exs index 068601f..d81ca43 100644 --- a/apps/massa_proxy/mix.exs +++ b/apps/massa_proxy/mix.exs @@ -12,7 +12,10 @@ defmodule MassaProxy.MixProject do lockfile: "../../mix.lock", start_permanent: Mix.env() == :prod, deps: deps(), - releases: releases() + releases: releases(), + aliases: [ + test: "test --no-start" + ] ] end @@ -21,7 +24,8 @@ defmodule MassaProxy.MixProject do [ extra_applications: [ :logger, - :observer + :observer, + :runtime ], mod: {MassaProxy, []} ] @@ -31,34 +35,25 @@ defmodule MassaProxy.MixProject do defp deps do [ # Base deps - {:bakeware, "~> 0.2"}, {:cloudstate_protocol, in_umbrella: true}, - {:injectx, "~> 0.1"}, - {:wasmex, "~> 0.5"}, - {:toml, "~> 0.6", override: true}, - {:flow, "~> 1.0"}, + {:eigr_protocol, in_umbrella: true}, + {:runtime, in_umbrella: true}, + {:runtime_grpc, in_umbrella: true}, + {:runtime_wasm, in_umbrella: true}, + {:store, in_umbrella: true}, + {:store_inmemory, in_umbrella: true}, + {:bakeware, "~> 0.2"}, {:vapor, "~> 0.10"}, - # Grpc deps - {:protobuf, "~> 0.9.0", override: true}, - {:grpc, github: "elixir-grpc/grpc", override: true}, - {:cowlib, "~> 2.11", override: true}, - {:grpc_prometheus, "~> 0.1"}, - {:jason, "~> 1.2"}, - # Cluster deps {:libcluster, "~> 3.3"}, {:horde, "~> 0.8"}, - {:phoenix_pubsub, "~> 2.0"}, {:nebulex, "~> 2.1"}, {:ranch, "~> 1.8"}, # Observability deps {:ex_ray, "~> 0.1"}, {:hackney, "~> 1.16"}, - {:prometheus, "~> 4.6"}, - {:prometheus_plugs, "~> 1.1"}, - {:telemetry, "~> 0.4.3"}, # Http facilities {:plug_cowboy, "~> 2.3"}, @@ -66,7 +61,10 @@ defmodule MassaProxy.MixProject do # Best practices {:credo, "~> 1.5", only: [:dev, :test], runtime: false}, - {:churn, "~> 0.1", only: :dev} + {:churn, "~> 0.1", only: :dev}, + + # Tests + {:local_cluster, "~> 1.2", only: [:test]} ] end diff --git a/apps/massa_proxy/test/test_helper.exs b/apps/massa_proxy/test/test_helper.exs index 869559e..dbed203 100644 --- a/apps/massa_proxy/test/test_helper.exs +++ b/apps/massa_proxy/test/test_helper.exs @@ -1 +1,8 @@ +# start the current node as a manager +:ok = LocalCluster.start() + +# start your application tree manually +Application.ensure_all_started(:massa_proxy) + +# run all tests! ExUnit.start() diff --git a/apps/runtime/.formatter.exs b/apps/runtime/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/apps/runtime/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/apps/runtime/.gitignore b/apps/runtime/.gitignore new file mode 100644 index 0000000..ed71b30 --- /dev/null +++ b/apps/runtime/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +runtime-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/apps/runtime/README.md b/apps/runtime/README.md new file mode 100644 index 0000000..ed263d1 --- /dev/null +++ b/apps/runtime/README.md @@ -0,0 +1,21 @@ +# Runtime + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `runtime` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:runtime, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/apps/massa_proxy/lib/massa_proxy/cluster/entity/entity_registry.ex b/apps/runtime/lib/entity/entity_registry.ex similarity index 70% rename from apps/massa_proxy/lib/massa_proxy/cluster/entity/entity_registry.ex rename to apps/runtime/lib/entity/entity_registry.ex index 1b8dc22..37c04d4 100644 --- a/apps/massa_proxy/lib/massa_proxy/cluster/entity/entity_registry.ex +++ b/apps/runtime/lib/entity/entity_registry.ex @@ -1,4 +1,4 @@ -defmodule MassaProxy.Entity.EntityRegistry do +defmodule Runtime.Entity.EntityRegistry do @moduledoc false use GenServer require Logger @@ -67,17 +67,48 @@ defmodule MassaProxy.Entity.EntityRegistry do end @impl true - def handle_call({:get, entity_type}, _from, state) do + def handle_call({:get, entity_type, service_name, method_name}, _from, state) do nodes = state |> Enum.reduce([], fn {key, value}, acc -> for entity <- value do - if entity.entity_type == entity_type do - [key] ++ acc + if entity.entity_type == entity_type and entity.service_name == service_name do + service_data = + Enum.map(entity.services, fn service -> + if service.name == get_simple_name(service_name) do + method_metadata = + Enum.map(service.methods, fn method -> + if method.name == method_name do + %{ + entity_type: entity_type, + service_name: get_simple_name(service_name), + full_service_name: service_name, + persistence_id: entity.persistence_id, + method_name: method.name, + method: method + } + else + %{} + end + end) + |> List.flatten() + |> Enum.uniq() + |> List.first() + + method_metadata + else + %{} + end + end) + |> List.flatten() + |> Enum.uniq() + + [%{node: key, entity: service_data}] ++ acc end end end) |> List.flatten() + |> Enum.reject(&is_nil/1) |> Enum.uniq() if Enum.all?(nodes, &is_nil/1) do @@ -160,9 +191,11 @@ defmodule MassaProxy.Entity.EntityRegistry do end # fetch current entities of the service - def lookup(entity_type) do - GenServer.call(__MODULE__, {:get, entity_type}) + def lookup(entity_type, service_name, method_name) do + GenServer.call(__MODULE__, {:get, entity_type, service_name, method_name}) end defp include_entities(state, message), do: Map.merge(state, message) + + defp get_simple_name(service_name), do: String.split(service_name, ".") |> List.last() end diff --git a/apps/massa_proxy/lib/massa_proxy/cluster/entity/entity_registry_supervisor.ex b/apps/runtime/lib/entity/entity_registry_supervisor.ex similarity index 73% rename from apps/massa_proxy/lib/massa_proxy/cluster/entity/entity_registry_supervisor.ex rename to apps/runtime/lib/entity/entity_registry_supervisor.ex index bd90c96..cc91ee3 100644 --- a/apps/massa_proxy/lib/massa_proxy/cluster/entity/entity_registry_supervisor.ex +++ b/apps/runtime/lib/entity/entity_registry_supervisor.ex @@ -1,4 +1,4 @@ -defmodule MassaProxy.Entity.EntityRegistry.Supervisor do +defmodule Runtime.Entity.EntityRegistry.Supervisor do @moduledoc false use Supervisor @@ -10,7 +10,7 @@ defmodule MassaProxy.Entity.EntityRegistry.Supervisor do def init(_args) do children = [ {Phoenix.PubSub, name: :entity_channel}, - MassaProxy.Entity.EntityRegistry.child_spec(%{}) + Runtime.Entity.EntityRegistry.child_spec(%{}) ] Supervisor.init(children, strategy: :one_for_one) diff --git a/apps/runtime/lib/protocol/command_processor.ex b/apps/runtime/lib/protocol/command_processor.ex new file mode 100644 index 0000000..b0946f3 --- /dev/null +++ b/apps/runtime/lib/protocol/command_processor.ex @@ -0,0 +1,12 @@ +defmodule Runtime.Protocol.CommandProcessor do + @moduledoc """ + CommandProcessor executes arbitrary logic on a command. + """ + + @type context :: any() + @type command :: any() + @type result :: any() + @type error :: any() + + @callback apply(context, command) :: {:ok, result} | {:error, error} +end diff --git a/apps/runtime/lib/protocol/handler.ex b/apps/runtime/lib/protocol/handler.ex new file mode 100644 index 0000000..4dcf2f1 --- /dev/null +++ b/apps/runtime/lib/protocol/handler.ex @@ -0,0 +1,12 @@ +defmodule Runtime.Protocol.Handler do + @moduledoc """ + This Behavior must be implemented by each entity protocol to handle + requests. + + Requests will be forwarded without the expectation of a return to the dispatcher + because the stream will be forwarded to the implementation of this Behavior, + leaving it to the handling and forwarding of an appropriate response to the caller + """ + + @callback handle(payload :: term) :: {:ok} | {:error, reason :: term} +end diff --git a/apps/runtime/lib/protocol/middleware.ex b/apps/runtime/lib/protocol/middleware.ex new file mode 100644 index 0000000..3f26e5e --- /dev/null +++ b/apps/runtime/lib/protocol/middleware.ex @@ -0,0 +1,253 @@ +defmodule Runtime.Protocol.Middleware do + @doc """ + Middleware is a bridge between the protocol and the user function. + The main purpose of middleware is to provide a way to add some abstraction between + the underlying transport, user function and the Entity processor. + + The main responsibility of this module's callbacks is to abstract the transport, that is, + the communication channel with the user role. + Processing rules should not be performed by the implementations of this module's callbacks. + """ + @type state :: any() + @type reason :: any() + + @callback do_init(state) :: + {:ok, state} + | {:ok, state, timeout() | :hibernate | {:continue, term()}} + | :ignore + | {:stop, reason :: any()} + + @callback handle_effect(any()) :: {:ok, any()} | {:error, any()} + + @callback handle_forward(any(), any()) :: {:ok, any()} | {:error, any()} + + @callback handle_unary(any(), any()) :: {:ok, any()} | {:error, any()} + + @callback handle_streamed(any(), any()) :: {:ok, Stream.t()} | {:error, any()} + + @callback handle_stream_in(any(), Stream.t()) :: {:ok, any()} | {:error, any()} + + @callback handle_stream_out(any(), any()) :: {:ok, Stream.t()} | {:error, any()} + + def do_init(state), do: {:ok, state, :hibernate} + + def handle_effect(_context) do + raise "Not implemented" + end + + def handle_forward(_context, _message) do + raise "Not implemented" + end + + def handle_unary(_context, _message) do + raise "Not implemented" + end + + def handle_streamed(_context, _messages) do + raise "Not implemented" + end + + def handle_stream_in(_context, _messages) do + raise "Not implemented" + end + + def handle_stream_out(_context, _message) do + raise "Not implemented" + end + + defoverridable do_init: 1, + handle_effect: 1, + handle_forward: 2, + handle_unary: 2, + handle_streamed: 2, + handle_stream_in: 2, + handle_stream_out: 2 + + defmacro __using__(opts) do + quote bind_quoted: [opts: opts] do + @behaviour Runtime.Protocol.Middleware + use GenServer + + require Logger + + alias Cloudstate.{Action.ActionResponse, SideEffect} + alias Runtime.Protocol.Router + + alias Runtime + + @command_processor opts[:command_processor] + + def child_spec(state \\ %{}) do + %{ + id: __MODULE__, + start: {__MODULE__, :start_link, [state]}, + shutdown: 60_000, + restart: :transient + } + end + + def start_link(%{entity_type: name} = state) do + GenServer.start_link(__MODULE__, state, name: name) + end + + @impl true + def init(state) do + do_init(state) + end + + @impl true + def handle_call( + {:handle_unary, %{context: context, payload: message} = _input}, + _from, + state + ) do + result = + with {:ok, %{side_effects: effects} = command} <- handle_unary(context, message), + {:ok, result} <- @command_processor.apply(context, command) do + call_effects(context, effects) + {:ok, result} + else + {:error, reason} -> {:error, "Failure to make unary request #{inspect(reason)}"} + end + + Logger.debug("Middleware User function response #{inspect(result)}") + + {:reply, result, state} + end + + @impl true + def handle_call( + {:handle_streamed, %{context: context, payload: messages} = _input}, + from, + state + ) do + spawn(fn -> + stream_result = + with {:ok, consumer_stream} <- handle_streamed(context, messages) do + consumer_stream = + consumer_stream + |> Stream.map(fn + {:ok, %{side_effects: effects} = command} -> + Logger.debug("Consumer Stream result: #{inspect(command)}") + + result = + case @command_processor.apply(context, command) do + {:ok, result} -> + {:ok, result} + + {:error, reason} -> + {:error, "Failure on process command #{inspect(reason)}"} + end + + call_effects(context, effects) + result + + {:error, reason} -> + {:error, "Failure on process client stream #{inspect(reason)}"} + end) + |> Enum.to_list() + + {:ok, consumer_stream} + else + {:ok, []} -> + {:error, "Client not returned a stream"} + + {:error, reason} -> + {:error, reason} + end + + GenServer.reply(from, stream_result) + end) + + {:noreply, state} + end + + @impl true + def handle_cast({:handle_effect, context}, state) do + with {:ok, %{side_effects: effects} = command} <- handle_effect(context), + {:ok, result} <- @command_processor.apply(context, command) do + Logger.debug( + "Handle effects User function response #{inspect(command)}. With commands result #{inspect(result)}" + ) + + call_effects(context, effects) + else + {:error, reason} -> + Logger.warn("Failure to make unary request #{inspect(reason)}") + end + + {:noreply, state} + end + + defp call_effects(_ctx, []), do: {:ok, []} + + defp call_effects( + %{entity_type: entity_type} = _ctx, + effects + ) + when is_list(effects) and length(effects) > 0 do + Enum.each(effects, fn %SideEffect{ + service_name: service_name, + command_name: command_name, + synchronous: synchronous, + payload: %Google.Protobuf.Any{type_url: input_type} = payload + } = effect -> + Logger.debug( + "Handling side effect #{inspect(effect)}} with command name: #{command_name} and input type: #{input_type}" + ) + + message = %{ + message: payload, + entity_type: nil, + service_name: nil, + request_type: nil, + original_method: nil, + input_type: nil, + output_type: nil, + persistence_id: nil, + stream: nil + } + + Router.route( + entity_type, + service_name, + command_name, + input_type, + !synchronous, + __MODULE__, + :effect, + message + ) + end) + end + + defp call_effects(_ctx, _), do: {:ok, []} + + # end quoted + end + + # end defmacro + end + + # Client API + def unary(%{entity_type: entity_type} = ctx, message) do + GenServer.call(get_name(entity_type), {:handle_unary, %{context: ctx, payload: message}}) + end + + def streamed(%{entity_type: entity_type} = ctx, messages) do + GenServer.call(get_name(entity_type), {:handle_streamed, %{context: ctx, payload: messages}}) + end + + def effect(%{entity_type: entity_type} = ctx) do + GenServer.cast(get_name(entity_type), {:handle_effect, ctx}) + end + + defp get_name(entity_type) do + mod = + entity_type + |> String.split(".") + |> Enum.at(-1) + + Module.concat(__MODULE__, mod) + end +end diff --git a/apps/runtime/lib/protocol/router.ex b/apps/runtime/lib/protocol/router.ex new file mode 100644 index 0000000..32c940a --- /dev/null +++ b/apps/runtime/lib/protocol/router.ex @@ -0,0 +1,119 @@ +defmodule Runtime.Protocol.Router do + @doc """ + Dispatch the given `mod`, `fun`, `args` request + to the appropriate node based on the `bucket`. + """ + require Logger + + alias ProxyRuntime.TaskSupervisor + alias Runtime.{Entity.EntityRegistry, Util} + + @timeout 10000 + + def route( + entity_type, + service_name, + command_name, + input_type, + async \\ false, + mod, + fun, + %{message: payload} = message + ) do + Logger.debug("Routing #{mod}:#{fun}") + + with node_entities <- EntityRegistry.lookup(entity_type, service_name, command_name) do + targets = + Enum.map(node_entities, fn %{node: member, entity: entity} = _node_entity -> + if member == node() do + {:local, node(), entity} + else + {:remote, member, entity} + end + end) + |> List.flatten() + + result = + case Enum.find(targets, fn target -> match?({:local, _, _}, target) end) do + {:local, _member, entities} -> + entity = List.first(entities) + + message = %{ + message + | entity_type: entity_type, + service_name: entity.full_service_name, + request_type: Util.get_type(entity.method), + original_method: entity.method_name, + input_type: input_type, + output_type: to_module(entity.method.output_type), + persistence_id: entity.persistence_id, + message: payload, + stream: nil + } + + apply(mod, fun, [message]) + + nil -> + {:remote, member, entities} = List.first(targets) + entity = List.first(entities) + + message = %{ + message + | entity_type: entity_type, + service_name: entity.full_service_name, + request_type: Util.get_type(entity.method), + original_method: entity.method_name, + input_type: input_type, + output_type: to_module(entity.method.output_type), + persistence_id: entity.persistence_id, + message: payload, + stream: nil + } + + call(member, async, mod, fun, message) + end + + result + else + [] -> {:unrouted, :not_found} + end + end + + defp call(node, true, mod, fun, args) do + Logger.info("Invoking async remote call on node #{inspect(node)}") + + pid = + Node.spawn(node, fn -> + Kernel.apply(mod, fun, [args]) + end) + + {:routed, :fire_and_forget, pid} + end + + defp call(node, false, mod, fun, args) do + Logger.info("Invoking sync remote call on node #{inspect(node)}") + + remote_result = + {TaskSupervisor, node} + |> Task.Supervisor.async(mod, fun, [args]) + |> Task.await(@timeout) + + {:routed, remote_result} + end + + defp to_module(name) do + pre_mod = + name + |> String.split(".") + |> Enum.reject(fn elem -> if elem == "", do: true end) + |> Enum.map(&String.capitalize(&1)) + + mod = + ["Elixir"] + |> Enum.concat(pre_mod) + |> Enum.join(".") + |> String.to_atom() + + mod + end +end diff --git a/apps/runtime/lib/runtime.ex b/apps/runtime/lib/runtime.ex new file mode 100644 index 0000000..0e5ce44 --- /dev/null +++ b/apps/runtime/lib/runtime.ex @@ -0,0 +1,72 @@ +defmodule Runtime do + @moduledoc """ + `Runtime`. + """ + use Supervisor + + alias Runtime.Protocol.Middleware + + defmodule MiddlewareDefinition do + defstruct entity_type: nil, module: nil + + @type t(entity_type, module) :: %MiddlewareDefinition{ + entity_type: entity_type, + module: module + } + + @type t :: %MiddlewareDefinition{entity_type: String.t(), module: module()} + end + + defmodule State do + defstruct middlewares: [] + + @type t(middlewares) :: %State{middlewares: middlewares} + + @type t :: %State{middlewares: list(%MiddlewareDefinition{})} + end + + @spec start_link(State.t()) :: :ignore | {:error, any} | {:ok, pid} + def start_link(state \\ %{}) do + Supervisor.start_link(__MODULE__, state, name: __MODULE__) + end + + @impl true + def init(%State{middlewares: middlewares} = _state) do + middleware_children = + Enum.map(middlewares, fn %MiddlewareDefinition{entity_type: type, module: module} = + _middleware -> + process_name = get_name(type) + module.child_spec(process_name) + end) + + children = + [ + Runtime.Entity.EntityRegistry.child_spec(%{}) + ] ++ middleware_children + + Supervisor.init(children, strategy: :one_for_one) + end + + # @impl true + # def start(_type, _args) do + # children = + # [ + # {Task.Supervisor, name: ProxyRuntime.TaskSupervisor}, + # {Runtime.Entity.EntityRegistry.Supervisor, [%{}]} + # ] + # |> Stream.reject(&is_nil/1) + # |> Enum.to_list() + + # opts = [strategy: :one_for_one, name: ProxyRuntime.Supervisor] + # Supervisor.start_link(children, opts) + # end + + defp get_name(entity_type) do + mod = + entity_type + |> String.split(".") + |> Enum.at(-1) + + Module.concat(Middleware, mod) + end +end diff --git a/apps/runtime/lib/util.ex b/apps/runtime/lib/util.ex new file mode 100644 index 0000000..7cc2260 --- /dev/null +++ b/apps/runtime/lib/util.ex @@ -0,0 +1,124 @@ +defmodule Runtime.Util do + @moduledoc false + require Logger + + def contains_key?(field_descriptor) do + Logger.debug("FieldOptions: #{inspect(field_descriptor)}") + + entity_key_ext = + Google.Protobuf.FieldOptions.get_extension( + field_descriptor.options, + Cloudstate.PbExtension, + :entity_key + ) + + Logger.debug("Entity key extension: #{inspect(entity_key_ext)}") + entity_key_ext + end + + def get_http_rule(method_descriptor) do + Logger.debug("MethodOptions HTTP Rules: #{inspect(method_descriptor)}") + + Google.Protobuf.MethodOptions.get_extension( + method_descriptor.options, + Google.Api.PbExtension, + :http + ) + end + + def get_eventing_rule(method_descriptor) do + Logger.debug("MethodOptions Eventing Rules: #{inspect(method_descriptor)}") + + evt_ext = + Google.Protobuf.MethodOptions.get_extension( + method_descriptor.options, + Cloudstate.PbExtension, + :eventing + ) + + Logger.debug("Eventing extension: #{inspect(evt_ext)}") + evt_ext + end + + def get_type(method) do + type = + cond do + method.unary == true -> "unary" + method.streamed == true -> "streamed" + method.stream_in == true -> "stream_in" + method.stream_out == true -> "stream_out" + end + + type + end + + def get_type_url(type) when is_binary(type) do + if String.contains?(type, "type.googleapis.com/") do + type + else + raise "Invalid type: #{type}" + end + end + + def get_type_url(type) when is_atom(type) do + parts = + type + |> to_string + |> String.replace("Elixir.", "") + |> String.split(".") + + package_name = + with {_, list} <- parts |> List.pop_at(-1), + do: list |> Stream.map(&String.downcase(&1)) |> Enum.join(".") + + type_name = parts |> List.last() + "type.googleapis.com/#{package_name}.#{type_name}" + end + + def compile(file) do + Code.compile_string(file) + rescue + error in UndefinedFunctionError -> + Logger.error("Error in Module definition. Make sure the service name is correct") + raise error + + error -> + Logger.error("Error during Service compilation phase #{inspect(error)}") + end + + def normalize_service_name(name) do + name + |> String.split(".") + |> Stream.map(&Macro.camelize(&1)) + |> Enum.join(".") + end + + def normalize_method_name(name), do: Macro.underscore(name) + + def get_module(filename, bindings \\ []), do: EEx.eval_file(filename, bindings) + + @doc """ + Get client gRPC connection when Runtime is a gRPC runtime. + """ + def get_connection(), + do: + GRPC.Stub.connect(get_address(is_uds_enable?()), + interceptors: [GRPC.Logger.Client], + adapter_opts: %{http2_opts: %{keepalive: 10000}} + ) + + def get_uds_address(), + do: Application.get_env(:massa_proxy, :user_function_sock_addr, "/var/run/cloudstate.sock") + + def is_uds_enable?(), + do: Application.get_env(:massa_proxy, :user_function_uds_enable, false) + + defp get_function_host(), + do: Application.get_env(:massa_proxy, :user_function_host, "127.0.0.1") + + def get_function_port(), do: Application.get_env(:massa_proxy, :user_function_port, 8080) + + def get_address(false), do: "#{get_function_host()}:#{get_function_port()}" + + def get_address(true), do: "#{get_uds_address()}" +end diff --git a/apps/runtime/mix.exs b/apps/runtime/mix.exs new file mode 100644 index 0000000..0968cda --- /dev/null +++ b/apps/runtime/mix.exs @@ -0,0 +1,45 @@ +defmodule Runtime.MixProject do + use Mix.Project + + def project do + [ + app: :runtime, + version: "0.1.0", + build_path: "../../_build", + config_path: "../../config/config.exs", + deps_path: "../../deps", + lockfile: "../../mix.lock", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + mod: {Runtime, []}, + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:cloudstate_protocol, in_umbrella: true}, + {:eigr_protocol, in_umbrella: true}, + {:injectx, "~> 0.1"}, + {:flow, "~> 1.0"}, + {:protobuf, "~> 0.9.0", override: true}, + {:grpc, github: "elixir-grpc/grpc", override: true}, + {:cowlib, "~> 2.11", override: true}, + {:grpc_prometheus, "~> 0.1"}, + {:jason, "~> 1.2"}, + {:toml, "~> 0.6", override: true}, + {:prometheus, "~> 4.6"}, + {:prometheus_plugs, "~> 1.1"}, + {:telemetry, "~> 0.4.3"}, + {:phoenix_pubsub, "~> 2.0"} + ] + end +end diff --git a/apps/runtime/test/runtime_test.exs b/apps/runtime/test/runtime_test.exs new file mode 100644 index 0000000..0a10dbb --- /dev/null +++ b/apps/runtime/test/runtime_test.exs @@ -0,0 +1,8 @@ +defmodule RuntimeTest do + use ExUnit.Case + doctest Runtime + + test "greets the world" do + assert Runtime.hello() == :world + end +end diff --git a/apps/runtime/test/test_helper.exs b/apps/runtime/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/apps/runtime/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/apps/runtime_grpc/.formatter.exs b/apps/runtime_grpc/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/apps/runtime_grpc/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/apps/runtime_grpc/.gitignore b/apps/runtime_grpc/.gitignore new file mode 100644 index 0000000..d5b30a5 --- /dev/null +++ b/apps/runtime_grpc/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +runtime_grpc-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/apps/runtime_grpc/README.md b/apps/runtime_grpc/README.md new file mode 100644 index 0000000..b6e9d28 --- /dev/null +++ b/apps/runtime_grpc/README.md @@ -0,0 +1,21 @@ +# RuntimeGrpc + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `runtime_grpc` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:runtime_grpc, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/apps/runtime_grpc/lib/protocol/action/action_middleware.ex b/apps/runtime_grpc/lib/protocol/action/action_middleware.ex new file mode 100644 index 0000000..1d59123 --- /dev/null +++ b/apps/runtime_grpc/lib/protocol/action/action_middleware.ex @@ -0,0 +1,73 @@ +defmodule Runtime.GRPC.Protocol.Action.Middleware do + use Runtime.Protocol.Middleware, + command_processor: Runtime.GRPC.Protocol.Action.Processor + + alias Cloudstate.Action.ActionProtocol.Stub, as: ActionClient + alias Runtime.GRPC.Protocol.Action.Protocol, as: ActionProtocol + alias Runtime.Util + + @impl true + def do_init(state), do: {:ok, state} + + @impl true + def handle_effect(context) do + with message <- ActionProtocol.build_msg(context), + {:ok, channel} <- Util.get_connection(), + {:ok, commands} <- ActionClient.handle_unary(channel, message) do + {:ok, commands} + else + {:error, reason} -> + {:error, {:error, "Failure to make side effect request #{inspect(reason)}"}} + end + end + + @impl true + def handle_forward(_context, _message) do + raise "Not implemented" + end + + @impl true + def handle_unary(_context, message) do + with {:ok, channel} <- Util.get_connection(), + {:ok, command} <- ActionClient.handle_unary(channel, message) do + {:ok, command} + else + {:error, reason} -> {:error, "Failure to make unary request #{inspect(reason)}"} + end + end + + @impl true + def handle_streamed(_context, messages) do + with {:ok, channel} <- Util.get_connection(), + client_stream = ActionClient.handle_streamed(channel), + :ok <- run_stream(client_stream, messages) |> Stream.run(), + {:ok, consumer_stream} <- GRPC.Stub.recv(client_stream) do + {:ok, Enum.to_list(consumer_stream)} + else + {:error, reason} -> {:error, "Failure to make streamed request #{inspect(reason)}"} + end + end + + @impl true + def handle_stream_in(_context, _messages) do + raise "Not implemented" + end + + @impl true + def handle_stream_out(_context, _message) do + raise "Not implemented" + end + + defp run_stream(client_stream, messages) do + messages + |> Stream.map(&send_stream_msg(client_stream, &1)) + end + + defp send_stream_msg(client_stream, :halt) do + GRPC.Stub.end_stream(client_stream) + end + + defp send_stream_msg(client_stream, msg) do + GRPC.Stub.send_request(client_stream, msg, []) + end +end diff --git a/apps/runtime_grpc/lib/protocol/action/action_processor.ex b/apps/runtime_grpc/lib/protocol/action/action_processor.ex new file mode 100644 index 0000000..4af64a3 --- /dev/null +++ b/apps/runtime_grpc/lib/protocol/action/action_processor.ex @@ -0,0 +1,42 @@ +defmodule Runtime.GRPC.Protocol.Action.Processor do + @moduledoc """ + This module defines the command processor for actions. + """ + require Logger + + alias Cloudstate.Action.ActionResponse + + @behaviour Runtime.Protocol.CommandProcessor + + def apply( + _context, + %ActionResponse{response: {:reply, %Cloudstate.Reply{} = _reply}} = message + ) do + {:ok, message} + end + + def apply( + _context, + %ActionResponse{response: {:failure, %Cloudstate.Failure{} = _failure}} = message + ) do + {:ok, message} + end + + def apply( + _context, + %ActionResponse{response: {:forward, %Cloudstate.Forward{} = _forward}} = message + ) do + {:ok, message} + end + + def apply( + _context, + %ActionResponse{response: nil} = _message + ) do + {:ok, %ActionResponse{}} + end + + def apply(nil, _context, message) do + {:ok, message} + end +end diff --git a/apps/runtime_grpc/lib/protocol/action/action_protocol.ex b/apps/runtime_grpc/lib/protocol/action/action_protocol.ex new file mode 100644 index 0000000..ad23139 --- /dev/null +++ b/apps/runtime_grpc/lib/protocol/action/action_protocol.ex @@ -0,0 +1,101 @@ +defmodule Runtime.GRPC.Protocol.Action.Protocol do + require Logger + + alias Cloudstate.{Action.ActionCommand, Action.ActionResponse, Metadata} + alias Google.Protobuf.Any + alias Runtime.Util + + @type t :: map() + @type command_type :: :payload | :metadata | :full + + @spec decode(t(), ActionReponse.t()) :: term() + def decode(%{output_type: output_mod}, %ActionResponse{response: {_action, payload}}) do + decode_payload(output_mod, payload) + end + + @spec build_msg(t(), command_type()) :: ActionComand.t() + def build_msg(ctx, command_type \\ :full) + + def build_msg(ctx, :full) do + cmd = build_msg(ctx, :metadata) + + %{cmd | payload: build_payload(ctx)} + end + + def build_msg(%{service_name: service_name, original_method: original_method}, :metadata) do + ActionCommand.new( + service_name: service_name, + name: original_method, + metadata: Metadata.new() + ) + end + + def build_msg(%{service_name: service_name, original_method: original_method} = ctx, :payload) do + ActionCommand.new( + service_name: service_name, + name: original_method, + metadata: Metadata.new(), + payload: build_payload(ctx) + ) + end + + @spec build_stream(t()) :: Enumerable.t() + def build_stream( + %{service_name: service_name, original_method: original_method, message: msgs} = state + ) do + # The first message in will contain the request metadata, including the + # service name and command name. It will not have an associated payload set. + # This will be followed by zero to many messages in with a payload + init_command = [ + ActionCommand.new( + service_name: service_name, + name: original_method, + metadata: Metadata.new() + ) + ] + + init_command + |> Stream.concat(msgs) + # Need to signal end_of_stream so attach a token to + # end of the stream so that we can call `GRPC.Stub.end_stream` + |> Stream.concat([:halt]) + |> Stream.transform({:pre_send, state}, &transform/2) + end + + defp transform(:halt, _acc) do + {[:halt], :halt} + end + + defp transform(_msg, {:pre_send, state}) do + command = build_msg(state, :metadata) + + {[command], {:sending, state}} + end + + defp transform(msg, {:sending, state} = acc) do + command = build_msg(%{state | message: msg}, :payload) + {[command], acc} + end + + defp build_payload(%{input_type: input_type, message: msg}) when is_binary(input_type), do: msg + + defp build_payload(%{input_type: input_type, message: msg}) when is_atom(input_type), + do: + Any.new( + type_url: Util.get_type_url(input_type), + value: input_type.encode(msg) + ) + + # defp decode_payload(output_mod, %{payload: %Any{value: bin}}) when is_binary(output_mod) do + # mod = + # Any.new( + # type_url: Util.get_type_url("type.googleapis.com/cloudstate.tck.model.action.Response"), + # value: bin + # ) + + # mod.decode(bin) + # end + + defp decode_payload(output_mod, %{payload: %Any{value: bin}}) when is_atom(output_mod), + do: output_mod.decode(bin) +end diff --git a/apps/runtime_grpc/lib/runtime_grpc.ex b/apps/runtime_grpc/lib/runtime_grpc.ex new file mode 100644 index 0000000..ed81550 --- /dev/null +++ b/apps/runtime_grpc/lib/runtime_grpc.ex @@ -0,0 +1,5 @@ +defmodule Runtime.GRPC do + @moduledoc """ + Documentation for `Runtime.Grpc`. + """ +end diff --git a/apps/runtime_grpc/mix.exs b/apps/runtime_grpc/mix.exs new file mode 100644 index 0000000..89678b7 --- /dev/null +++ b/apps/runtime_grpc/mix.exs @@ -0,0 +1,33 @@ +defmodule RuntimeGrpc.MixProject do + use Mix.Project + + def project do + [ + app: :runtime_grpc, + version: "0.1.0", + build_path: "../../_build", + config_path: "../../config/config.exs", + deps_path: "../../deps", + lockfile: "../../mix.lock", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:cloudstate_protocol, in_umbrella: true}, + {:eigr_protocol, in_umbrella: true}, + {:runtime, in_umbrella: true} + ] + end +end diff --git a/apps/runtime_grpc/test/runtime_grpc_test.exs b/apps/runtime_grpc/test/runtime_grpc_test.exs new file mode 100644 index 0000000..da1c4ca --- /dev/null +++ b/apps/runtime_grpc/test/runtime_grpc_test.exs @@ -0,0 +1,4 @@ +defmodule Runtime.GRPCTest do + use ExUnit.Case + doctest Runtime.GRPC +end diff --git a/apps/runtime_grpc/test/test_helper.exs b/apps/runtime_grpc/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/apps/runtime_grpc/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/apps/runtime_wasm/.formatter.exs b/apps/runtime_wasm/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/apps/runtime_wasm/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/apps/runtime_wasm/.gitignore b/apps/runtime_wasm/.gitignore new file mode 100644 index 0000000..3de611c --- /dev/null +++ b/apps/runtime_wasm/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +runtime_wasm-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/apps/runtime_wasm/README.md b/apps/runtime_wasm/README.md new file mode 100644 index 0000000..c9c9cb2 --- /dev/null +++ b/apps/runtime_wasm/README.md @@ -0,0 +1,21 @@ +# RuntimeWasm + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `runtime_wasm` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:runtime_wasm, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/apps/runtime_wasm/lib/runtime_wasm.ex b/apps/runtime_wasm/lib/runtime_wasm.ex new file mode 100644 index 0000000..e3a8ff8 --- /dev/null +++ b/apps/runtime_wasm/lib/runtime_wasm.ex @@ -0,0 +1,18 @@ +defmodule RuntimeWasm do + @moduledoc """ + Documentation for `RuntimeWasm`. + """ + + @doc """ + Hello world. + + ## Examples + + iex> RuntimeWasm.hello() + :world + + """ + def hello do + :world + end +end diff --git a/apps/runtime_wasm/mix.exs b/apps/runtime_wasm/mix.exs new file mode 100644 index 0000000..a4a6229 --- /dev/null +++ b/apps/runtime_wasm/mix.exs @@ -0,0 +1,33 @@ +defmodule RuntimeWasm.MixProject do + use Mix.Project + + def project do + [ + app: :runtime_wasm, + version: "0.1.0", + build_path: "../../_build", + config_path: "../../config/config.exs", + deps_path: "../../deps", + lockfile: "../../mix.lock", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:runtime, in_umbrella: true}, + {:wasmex, "~> 0.5"}, + {:toml, "~> 0.6", override: true} + ] + end +end diff --git a/apps/runtime_wasm/test/runtime_wasm_test.exs b/apps/runtime_wasm/test/runtime_wasm_test.exs new file mode 100644 index 0000000..fcab4c8 --- /dev/null +++ b/apps/runtime_wasm/test/runtime_wasm_test.exs @@ -0,0 +1,8 @@ +defmodule RuntimeWasmTest do + use ExUnit.Case + doctest RuntimeWasm + + test "greets the world" do + assert RuntimeWasm.hello() == :world + end +end diff --git a/apps/runtime_wasm/test/test_helper.exs b/apps/runtime_wasm/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/apps/runtime_wasm/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/apps/store/.formatter.exs b/apps/store/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/apps/store/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/apps/store/.gitignore b/apps/store/.gitignore new file mode 100644 index 0000000..1201402 --- /dev/null +++ b/apps/store/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +store-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/apps/store/README.md b/apps/store/README.md new file mode 100644 index 0000000..57f38f0 --- /dev/null +++ b/apps/store/README.md @@ -0,0 +1,21 @@ +# Store + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `store` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:store, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/apps/store/lib/store.ex b/apps/store/lib/store.ex new file mode 100644 index 0000000..bf82fbc --- /dev/null +++ b/apps/store/lib/store.ex @@ -0,0 +1,18 @@ +defmodule Store do + @moduledoc """ + Documentation for `Store`. + """ + + @doc """ + Hello world. + + ## Examples + + iex> Store.hello() + :world + + """ + def hello do + :world + end +end diff --git a/apps/store/mix.exs b/apps/store/mix.exs new file mode 100644 index 0000000..2968689 --- /dev/null +++ b/apps/store/mix.exs @@ -0,0 +1,33 @@ +defmodule Store.MixProject do + use Mix.Project + + def project do + [ + app: :store, + version: "0.1.0", + build_path: "../../_build", + config_path: "../../config/config.exs", + deps_path: "../../deps", + lockfile: "../../mix.lock", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + # {:dep_from_hexpm, "~> 0.3.0"}, + # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}, + # {:sibling_app_in_umbrella, in_umbrella: true} + ] + end +end diff --git a/apps/store/test/store_test.exs b/apps/store/test/store_test.exs new file mode 100644 index 0000000..86aa334 --- /dev/null +++ b/apps/store/test/store_test.exs @@ -0,0 +1,8 @@ +defmodule StoreTest do + use ExUnit.Case + doctest Store + + test "greets the world" do + assert Store.hello() == :world + end +end diff --git a/apps/store/test/test_helper.exs b/apps/store/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/apps/store/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/apps/store_inmemory/.formatter.exs b/apps/store_inmemory/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/apps/store_inmemory/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/apps/store_inmemory/.gitignore b/apps/store_inmemory/.gitignore new file mode 100644 index 0000000..388f86a --- /dev/null +++ b/apps/store_inmemory/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +store_inmemory-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/apps/store_inmemory/README.md b/apps/store_inmemory/README.md new file mode 100644 index 0000000..f261ebc --- /dev/null +++ b/apps/store_inmemory/README.md @@ -0,0 +1,21 @@ +# StoreInmemory + +**TODO: Add description** + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `store_inmemory` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:store_inmemory, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . + diff --git a/apps/store_inmemory/lib/store_inmemory.ex b/apps/store_inmemory/lib/store_inmemory.ex new file mode 100644 index 0000000..ff102ca --- /dev/null +++ b/apps/store_inmemory/lib/store_inmemory.ex @@ -0,0 +1,18 @@ +defmodule StoreInmemory do + @moduledoc """ + Documentation for `StoreInmemory`. + """ + + @doc """ + Hello world. + + ## Examples + + iex> StoreInmemory.hello() + :world + + """ + def hello do + :world + end +end diff --git a/apps/store_inmemory/mix.exs b/apps/store_inmemory/mix.exs new file mode 100644 index 0000000..2c40ab2 --- /dev/null +++ b/apps/store_inmemory/mix.exs @@ -0,0 +1,33 @@ +defmodule StoreInmemory.MixProject do + use Mix.Project + + def project do + [ + app: :store_inmemory, + version: "0.1.0", + build_path: "../../_build", + config_path: "../../config/config.exs", + deps_path: "../../deps", + lockfile: "../../mix.lock", + elixir: "~> 1.13", + start_permanent: Mix.env() == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + # {:dep_from_hexpm, "~> 0.3.0"}, + # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}, + # {:sibling_app_in_umbrella, in_umbrella: true} + ] + end +end diff --git a/apps/store_inmemory/test/store_inmemory_test.exs b/apps/store_inmemory/test/store_inmemory_test.exs new file mode 100644 index 0000000..a349ec1 --- /dev/null +++ b/apps/store_inmemory/test/store_inmemory_test.exs @@ -0,0 +1,8 @@ +defmodule StoreInmemoryTest do + use ExUnit.Case + doctest StoreInmemory + + test "greets the world" do + assert StoreInmemory.hello() == :world + end +end diff --git a/apps/store_inmemory/test/test_helper.exs b/apps/store_inmemory/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/apps/store_inmemory/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start() diff --git a/config/config.exs b/config/config.exs index 55c6b46..cf4cc04 100644 --- a/config/config.exs +++ b/config/config.exs @@ -44,7 +44,8 @@ config :massa_proxy, proxy_http_port: System.get_env("PROXY_HTTP_PORT", "9001") |> String.to_integer(), user_function_host: System.get_env("USER_FUNCTION_HOST", "127.0.0.1"), user_function_port: System.get_env("USER_FUNCTION_PORT", "8080") |> String.to_integer(), - user_function_uds_enable: System.get_env("PROXY_UDS_MODE", "false") |> String.to_existing_atom(), + user_function_uds_enable: + System.get_env("PROXY_UDS_MODE", "false") |> String.to_existing_atom(), user_function_sock_addr: System.get_env("PROXY_UDS_ADDRESS", "/var/run/cloudstate.sock"), heartbeat_interval: System.get_env("PROXY_HEARTBEAT_INTERVAL", "240000") |> String.to_integer() diff --git a/config/prod.exs b/config/prod.exs index 6fb52d6..46ef105 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -4,7 +4,7 @@ import Config config :logger, backends: [:console], compile_time_purge_matching: [ - [level_lower_than: :info] + [level_lower_than: :debug] ] config :protobuf, extensions: :enabled diff --git a/mix.exs b/mix.exs index 1c9c10a..27045d6 100644 --- a/mix.exs +++ b/mix.exs @@ -1,4 +1,4 @@ -defmodule MongooseProxyProject.MixProject do +defmodule Massa.MixProject do use Mix.Project def project do @@ -6,7 +6,10 @@ defmodule MongooseProxyProject.MixProject do apps_path: "apps", version: "0.1.0", start_permanent: Mix.env() == :prod, - deps: deps() + deps: deps(), + aliases: [ + test: "test --no-start" + ] ] end diff --git a/mix.lock b/mix.lock index 2dcf416..d427a70 100644 --- a/mix.lock +++ b/mix.lock @@ -16,6 +16,7 @@ "flow": {:hex, :flow, "1.1.0", "b569c1042cb2da97103f6d70a0267a5657dce1402f41b4020bef98bbef9c7c1e", [:mix], [{:gen_stage, "~> 1.0", [hex: :gen_stage, repo: "hexpm", optional: false]}], "hexpm", "066f42f7a1ea6a86cb4ef763310338981a5cfb93bcebce10863a23a4859fd785"}, "gen_stage": {:hex, :gen_stage, "1.1.0", "dd0c0f8d2f3b993fdbd3d58e94abbe65380f4e78bdee3fa93d5618d7d14abe60", [:mix], [], "hexpm", "7f2b36a6d02f7ef2ba410733b540ec423af65ec9c99f3d1083da508aca3b9305"}, "gen_state_machine": {:hex, :gen_state_machine, "3.0.0", "1e57f86a494e5c6b14137ebef26a7eb342b3b0070c7135f2d6768ed3f6b6cdff", [:mix], [], "hexpm", "0a59652574bebceb7309f6b749d2a41b45fdeda8dbb4da0791e355dd19f0ed15"}, + "global_flags": {:hex, :global_flags, "1.0.0", "ee6b864979a1fb38d1fbc67838565644baf632212bce864adca21042df036433", [:rebar3], [], "hexpm", "85d944cecd0f8f96b20ce70b5b16ebccedfcd25e744376b131e89ce61ba93176"}, "google_protos": {:hex, :google_protos, "0.2.0", "7c6280e288d7f04a58448444b12d937ddc8cc40dc3d1e4f61c69936ef71d4739", [:mix], [{:protobuf, "~> 0.8", [hex: :protobuf, repo: "hexpm", optional: false]}], "hexpm", "5de24802e89867cea544d0ee8cbd36f6c9c1ebd4a9fcc55276d6eeadeedcc1f5"}, "grpc": {:git, "https://github.com/elixir-grpc/grpc.git", "eff8a8828d27ddd7f63a3c1dd5aae86246df215e", []}, "grpc_prometheus": {:hex, :grpc_prometheus, "0.1.0", "a2f45ca83018c4ae59e4c293b7455634ac09e38c36cba7cc1fb8affdf462a6d5", [:mix], [{:grpc, ">= 0.0.0", [hex: :grpc, repo: "hexpm", optional: true]}, {:prometheus, "~> 4.0", [hex: :prometheus, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8b9ab3098657e7daec0b3edc78e1d02418bc0871618d8ca89b51b74a8086bb71"}, @@ -27,6 +28,7 @@ "jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"}, "libcluster": {:hex, :libcluster, "3.3.0", "f7d45ff56d88e9fb4c30aee662480cbab69ebc0e7f7da4ad8d01b1e4f7492da8", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "ecdcdc88334ec8eb18b10a13a1d5f22a3319a970b5b1e66cfe71c7719a4ab6cc"}, "libring": {:hex, :libring, "1.5.0", "44313eb6862f5c9168594a061e9d5f556a9819da7c6444706a9e2da533396d70", [:mix], [], "hexpm", "04e843d4fdcff49a62d8e03778d17c6cb2a03fe2d14020d3825a1761b55bd6cc"}, + "local_cluster": {:hex, :local_cluster, "1.2.1", "8eab3b8a387680f0872eacfb1a8bd5a91cb1d4d61256eec6a655b07ac7030c73", [:mix], [{:global_flags, "~> 1.0", [hex: :global_flags, repo: "hexpm", optional: false]}], "hexpm", "aae80c9bc92c911cb0be085fdeea2a9f5b88f81b6bec2ff1fec244bb0acc232c"}, "merkle_map": {:hex, :merkle_map, "0.2.1", "01a88c87a6b9fb594c67c17ebaf047ee55ffa34e74297aa583ed87148006c4c8", [:mix], [], "hexpm", "fed4d143a5c8166eee4fa2b49564f3c4eace9cb252f0a82c1613bba905b2d04d"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.1", "0de4c81303fe07806ebc2494d5321ce8fb4df106e34dd5f9d787b637ebadc256", [:mix], [], "hexpm", "7a86b920d2aedce5fb6280ac8261ac1a739ae6c1a1ad38f5eadf910063008942"},