├── .circleci └── config.yml ├── .devcontainer ├── Dockerfile ├── build.sh └── devcontainer.json ├── .dockerignore ├── .gitignore ├── .sbtopts ├── .scalafmt.conf ├── .travis.yml ├── Dockerfile.js-crdts ├── Dockerfile.js-shopping-cart ├── LICENSE ├── OLD-README.md ├── README.md ├── bin ├── deploy-cloudstate.sh ├── install-cassandra.sh ├── install-postgres.sh ├── prepare-minikube-linux.sh ├── run-java-eventsourced-shopping-cart-test.sh ├── run-java-shopping-cart-test.sh └── setup-devtools.sh ├── build.sbt ├── cloudstate-operator ├── .gitignore ├── Dockerfile ├── Makefile ├── PROJECT ├── README.md ├── cmd │ └── main.go ├── config │ ├── certmanager │ │ ├── certificate.yaml │ │ ├── kustomization.yaml │ │ └── kustomizeconfig.yaml │ ├── crd │ │ ├── bases │ │ │ ├── cloudstate.io_routes.yaml │ │ │ ├── cloudstate.io_statefulservices.yaml │ │ │ └── cloudstate.io_statefulstores.yaml │ │ ├── kustomization.yaml │ │ ├── kustomizeconfig.yaml │ │ └── patches │ │ │ ├── cainjection_in_routes.yaml │ │ │ ├── cainjection_in_statefulservices.yaml │ │ │ ├── cainjection_in_statefulstores.yaml │ │ │ ├── fix-container-port-protocol-patch.yaml │ │ │ ├── webhook_in_routes.yaml │ │ │ ├── webhook_in_statefulservices.yaml │ │ │ └── webhook_in_statefulstores.yaml │ ├── default │ │ ├── kustomization.yaml │ │ ├── manager_auth_proxy_patch.yaml │ │ ├── manager_webhook_patch.yaml │ │ └── webhookcainjection_patch.yaml │ ├── manager │ │ ├── configmap.yaml │ │ ├── kustomization.yaml │ │ └── manager.yaml │ ├── native-image │ │ ├── cloudstate-config-patch.yaml │ │ └── kustomization.yaml │ ├── prometheus │ │ ├── kustomization.yaml │ │ └── monitor.yaml │ ├── rbac │ │ ├── auth_proxy_role.yaml │ │ ├── auth_proxy_role_binding.yaml │ │ ├── auth_proxy_service.yaml │ │ ├── kustomization.yaml │ │ ├── leader_election_role.yaml │ │ ├── leader_election_role_binding.yaml │ │ ├── role.yaml │ │ └── role_binding.yaml │ ├── samples │ │ ├── cloudstate_v1alpha1_route.yaml │ │ ├── cloudstate_v1alpha1_statefulservice.yaml │ │ └── cloudstate_v1alpha1_statefulstore.yaml │ └── webhook │ │ ├── kustomization.yaml │ │ ├── kustomizeconfig.yaml │ │ ├── manifests.yaml │ │ └── service.yaml ├── go.mod ├── go.sum ├── hack │ └── boilerplate.go.txt ├── internal │ └── google │ │ └── api │ │ └── sql.cnrm.cloud │ │ └── v1beta1 │ │ └── sqltypes.go ├── manifests │ ├── cloudstate-operator-native.yaml │ ├── cloudstate-operator.yaml │ └── crds.yaml └── pkg │ ├── apis │ └── v1alpha1 │ │ ├── groupversion_info.go │ │ ├── statefulservice_types.go │ │ ├── statefulstore_types.go │ │ └── zz_generated.deepcopy.go │ ├── config │ ├── doc.go │ ├── operator_config.go │ └── statefulservice_config.go │ ├── controllers │ ├── doc.go │ ├── statefulservice_controller.go │ ├── statefulservice_controller_test.go │ ├── statefulstore_controller.go │ ├── statefulstore_controller_test.go │ ├── suite_test.go │ └── test │ │ ├── cnrm-crds.yaml │ │ └── istio-crd.yaml │ ├── listeners │ └── statefulservice_listener.go │ ├── reconciliation │ └── reconciliation.go │ ├── stores │ ├── cassandra_store.go │ ├── doc.go │ ├── in_memory_store.go │ ├── no_store.go │ ├── postgres_store.go │ ├── spanner_store.go │ ├── store.go │ └── stores.go │ └── webhooks │ └── pod_injector.go ├── docs ├── .gitignore ├── Makefile ├── README.adoc ├── config │ └── validate-links.json └── src │ ├── antora.yml │ ├── modules │ ├── ROOT │ │ ├── nav.adoc │ │ ├── pages │ │ │ ├── cloudstate-solution.adoc │ │ │ ├── crud-limitations.adoc │ │ │ ├── examples.adoc │ │ │ ├── index.adoc │ │ │ ├── stateless-limitations.adoc │ │ │ └── working.adoc │ │ └── partials │ │ │ └── include.adoc │ ├── contribute │ │ ├── nav.adoc │ │ └── pages │ │ │ ├── architecture.adoc │ │ │ ├── build-native.adoc │ │ │ ├── getting-started.adoc │ │ │ ├── graalvm-integration.adoc │ │ │ ├── index.adoc │ │ │ ├── knative-integration.adoc │ │ │ ├── language-support.adoc │ │ │ ├── serialization.adoc │ │ │ └── testing.adoc │ ├── deploy │ │ ├── nav.adoc │ │ └── pages │ │ │ ├── autoscaling.adoc │ │ │ ├── cassandra.adoc │ │ │ ├── deploying.adoc │ │ │ ├── index.adoc │ │ │ ├── inmemory.adoc │ │ │ ├── install-production.adoc │ │ │ ├── monitoring.adoc │ │ │ ├── postgresql.adoc │ │ │ ├── security.adoc │ │ │ └── stateful-stores.adoc │ └── develop │ │ ├── nav.adoc │ │ └── pages │ │ ├── examples.adoc │ │ ├── gke.adoc │ │ ├── index.adoc │ │ ├── install.adoc │ │ ├── prerequisites.adoc │ │ └── tutorial.adoc │ └── shared │ ├── antora.yml │ └── modules │ ├── ROOT │ ├── images │ │ ├── abstract_over_state.png │ │ ├── data_model_crdts.png │ │ ├── data_model_event_sourcing.png │ │ ├── faas-crud.png │ │ ├── high-level-design.svg │ │ ├── powered_by_akka_sidecars.png │ │ └── serving_stateful_functions.png │ └── partials │ │ ├── architecture.adoc │ │ ├── cloudstate-solution.adoc │ │ ├── crud-limitations.adoc │ │ ├── examples.adoc │ │ ├── stateless-limitations.adoc │ │ └── working.adoc │ ├── concepts │ ├── images │ │ └── overview.svg │ ├── nav.adoc │ └── pages │ │ ├── crdts.adoc │ │ ├── effects.adoc │ │ ├── eventsourced.adoc │ │ ├── glossary.adoc │ │ ├── grpc.adoc │ │ └── index.adoc │ └── develop │ └── partials │ ├── install.adoc │ ├── prerequisites.adoc │ └── tutorial.adoc ├── graal-tools └── src │ └── main │ ├── java │ └── io │ │ └── cloudstate │ │ └── graaltools │ │ └── Substitutions.java │ └── scala │ └── io │ └── cloudstate │ └── graaltools │ ├── AkkaActorRegisterFeature.scala │ ├── Existence.scala │ └── ProtobufGeneratedMessageRegisterFeature.scala ├── images ├── abstract_over_state.png ├── data_model_crdts.png ├── data_model_event_sourcing.png ├── faas_with_crud.png ├── high-level-design.svg ├── powered_by_akka_sidecars.png └── serving_stateful_functions.png ├── java-support ├── docs │ ├── .gitignore │ ├── Makefile │ ├── config │ │ └── validate-links.json │ └── src │ │ ├── antora.yml │ │ └── modules │ │ └── java │ │ ├── examples │ │ ├── docs │ │ │ └── user │ │ │ │ ├── crdt │ │ │ │ └── ShoppingCartEntity.java │ │ │ │ ├── effects │ │ │ │ └── ShoppingCartEntity.java │ │ │ │ ├── eventsourced │ │ │ │ └── ShoppingCartEntity.java │ │ │ │ └── gettingstarted │ │ │ │ └── ShoppingCartMain.java │ │ └── proto │ │ │ ├── domain.proto │ │ │ ├── hotitems.proto │ │ │ └── shoppingcart.proto │ │ ├── nav.adoc │ │ ├── pages │ │ ├── api.adoc │ │ ├── crdt.adoc │ │ ├── effects.adoc │ │ ├── eventsourced.adoc │ │ ├── getting-started.adoc │ │ ├── index.adoc │ │ └── serialization.adoc │ │ └── partials │ │ └── include.adoc ├── src │ ├── main │ │ ├── java │ │ │ ├── io │ │ │ │ └── cloudstate │ │ │ │ │ └── javasupport │ │ │ │ │ ├── ClientActionContext.java │ │ │ │ │ ├── CloudEvent.java │ │ │ │ │ ├── CloudState.java │ │ │ │ │ ├── Context.java │ │ │ │ │ ├── EffectContext.java │ │ │ │ │ ├── EntityContext.java │ │ │ │ │ ├── EntityFactory.java │ │ │ │ │ ├── EntityId.java │ │ │ │ │ ├── EntityOptions.java │ │ │ │ │ ├── Jsonable.java │ │ │ │ │ ├── Metadata.java │ │ │ │ │ ├── MetadataContext.java │ │ │ │ │ ├── PassivationStrategy.java │ │ │ │ │ ├── ServiceCall.java │ │ │ │ │ ├── ServiceCallFactory.java │ │ │ │ │ ├── ServiceCallRef.java │ │ │ │ │ ├── action │ │ │ │ │ ├── Action.java │ │ │ │ │ ├── ActionContext.java │ │ │ │ │ ├── ActionHandler.java │ │ │ │ │ ├── ActionReply.java │ │ │ │ │ ├── CallHandler.java │ │ │ │ │ ├── Effect.java │ │ │ │ │ ├── FailureReply.java │ │ │ │ │ ├── ForwardReply.java │ │ │ │ │ ├── MessageEnvelope.java │ │ │ │ │ └── MessageReply.java │ │ │ │ │ ├── crdt │ │ │ │ │ ├── AbstractORMapWrapper.java │ │ │ │ │ ├── CommandContext.java │ │ │ │ │ ├── CommandHandler.java │ │ │ │ │ ├── Crdt.java │ │ │ │ │ ├── CrdtContext.java │ │ │ │ │ ├── CrdtCreationContext.java │ │ │ │ │ ├── CrdtEntity.java │ │ │ │ │ ├── CrdtEntityFactory.java │ │ │ │ │ ├── CrdtEntityHandler.java │ │ │ │ │ ├── CrdtEntityOptions.java │ │ │ │ │ ├── CrdtFactory.java │ │ │ │ │ ├── Flag.java │ │ │ │ │ ├── GCounter.java │ │ │ │ │ ├── GSet.java │ │ │ │ │ ├── LWWRegister.java │ │ │ │ │ ├── LWWRegisterMap.java │ │ │ │ │ ├── ORMap.java │ │ │ │ │ ├── ORSet.java │ │ │ │ │ ├── PNCounter.java │ │ │ │ │ ├── PNCounterMap.java │ │ │ │ │ ├── StreamCancelledContext.java │ │ │ │ │ ├── StreamedCommandContext.java │ │ │ │ │ ├── SubscriptionContext.java │ │ │ │ │ ├── Vote.java │ │ │ │ │ ├── WriteConsistency.java │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── entity │ │ │ │ │ ├── CommandContext.java │ │ │ │ │ ├── CommandHandler.java │ │ │ │ │ ├── Entity.java │ │ │ │ │ ├── EntityContext.java │ │ │ │ │ ├── EntityCreationContext.java │ │ │ │ │ ├── EntityFactory.java │ │ │ │ │ ├── EntityHandler.java │ │ │ │ │ ├── EntityOptions.java │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── eventsourced │ │ │ │ │ ├── CommandContext.java │ │ │ │ │ ├── CommandHandler.java │ │ │ │ │ ├── EventContext.java │ │ │ │ │ ├── EventHandler.java │ │ │ │ │ ├── EventSourcedContext.java │ │ │ │ │ ├── EventSourcedEntity.java │ │ │ │ │ ├── EventSourcedEntityCreationContext.java │ │ │ │ │ ├── EventSourcedEntityFactory.java │ │ │ │ │ ├── EventSourcedEntityHandler.java │ │ │ │ │ ├── EventSourcedEntityOptions.java │ │ │ │ │ ├── Snapshot.java │ │ │ │ │ ├── SnapshotContext.java │ │ │ │ │ ├── SnapshotHandler.java │ │ │ │ │ └── package-info.java │ │ │ │ │ ├── impl │ │ │ │ │ ├── CloudStateAnnotation.java │ │ │ │ │ └── package-info.java │ │ │ │ │ └── package-info.java │ │ │ └── overview.html │ │ ├── resources │ │ │ └── reference.conf │ │ └── scala │ │ │ └── io │ │ │ └── cloudstate │ │ │ └── javasupport │ │ │ ├── CloudStateRunner.scala │ │ │ └── impl │ │ │ ├── AnySupport.scala │ │ │ ├── Contexts.scala │ │ │ ├── EntityDiscoveryImpl.scala │ │ │ ├── EntityExceptions.scala │ │ │ ├── MetadataImpl.scala │ │ │ ├── PassivationStrategies.scala │ │ │ ├── ReflectionHelper.scala │ │ │ ├── ResolvedServiceCallFactory.scala │ │ │ ├── ResolvedServiceMethod.scala │ │ │ ├── action │ │ │ ├── ActionImpl.scala │ │ │ └── AnnotationBasedActionSupport.scala │ │ │ ├── crdt │ │ │ ├── AbstractCrdtFactory.scala │ │ │ ├── AnnotationBasedCrdtSupport.scala │ │ │ ├── CrdtDeltaTransformer.scala │ │ │ ├── CrdtEntityOptionsImpl.scala │ │ │ ├── CrdtImpl.scala │ │ │ ├── FlagImpl.scala │ │ │ ├── GCounterImpl.scala │ │ │ ├── GSetImpl.scala │ │ │ ├── InternalCrdt.scala │ │ │ ├── LWWRegisterImpl.scala │ │ │ ├── ORMapImpl.scala │ │ │ ├── ORSetImpl.scala │ │ │ ├── PNCounterImpl.scala │ │ │ └── VoteImpl.scala │ │ │ ├── entity │ │ │ ├── AnnotationBasedEntitySupport.scala │ │ │ ├── EntityImpl.scala │ │ │ └── EntityOptionsImpl.scala │ │ │ └── eventsourced │ │ │ ├── AnnotationBasedEventSourcedSupport.scala │ │ │ ├── EventSourcedEntityOptionsImpl.scala │ │ │ └── EventSourcedImpl.scala │ └── test │ │ ├── proto │ │ └── cloudstate │ │ │ └── javasupport │ │ │ └── actionspec.proto │ │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── javasupport │ │ └── impl │ │ ├── AnySupportSpec.scala │ │ ├── action │ │ ├── ActionServiceSpec.scala │ │ └── AnnotationBasedActionSupportSpec.scala │ │ ├── crdt │ │ └── AnnotationBasedCrdtSupportSpec.scala │ │ ├── entity │ │ ├── AnnotationBasedEntitySupportSpec.scala │ │ ├── EntityImplSpec.scala │ │ └── TestEntity.scala │ │ └── eventsourced │ │ ├── AnnotationBasedEventSourcedSupportSpec.scala │ │ ├── EventSourcedImplSpec.scala │ │ └── TestEventSourced.scala └── tck │ └── src │ └── main │ └── java │ └── io │ └── cloudstate │ └── javasupport │ └── tck │ ├── JavaSupportTck.java │ └── model │ ├── action │ ├── ActionTckModelBehavior.java │ └── ActionTwoBehavior.java │ ├── crdt │ ├── CrdtConfiguredEntity.java │ ├── CrdtTckModelEntity.java │ └── CrdtTwoEntity.java │ ├── eventlogeventing │ ├── EventLogSubscriber.java │ ├── EventSourcedEntityOne.java │ ├── EventSourcedEntityTwo.java │ └── JsonMessage.java │ ├── eventsourced │ ├── EventSourcedConfiguredEntity.java │ ├── EventSourcedTckModelEntity.java │ └── EventSourcedTwoEntity.java │ └── valuebased │ ├── ValueEntityConfiguredEntity.java │ ├── ValueEntityTckModelEntity.java │ └── ValueEntityTwoEntity.java ├── node-support ├── .gitignore ├── .npmrc ├── .nvmrc ├── LICENSE ├── README.md ├── RELEASING.md ├── bin │ ├── compile-descriptor.js │ ├── download-protoc.js │ └── prepare.sh ├── docs │ ├── .gitignore │ ├── Makefile │ └── src │ │ ├── antora.yml │ │ └── modules │ │ └── javascript │ │ ├── examples │ │ ├── .gitignore │ │ ├── .npmrc │ │ ├── .nvmrc │ │ ├── domain.proto │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── shoppingcart.proto │ │ └── test │ │ │ ├── eventsourced │ │ │ └── shoppingcart.js │ │ │ └── gettingstarted │ │ │ ├── index.js │ │ │ └── shoppingcart.js │ │ ├── nav.adoc │ │ └── pages │ │ ├── api.adoc │ │ ├── crdt.adoc │ │ ├── effects.adoc │ │ ├── eventsourced.adoc │ │ ├── getting-started.adoc │ │ ├── index.adoc │ │ └── serialization.adoc ├── index.js ├── jsdoc.json ├── package-lock.json ├── package.json ├── src │ ├── action-support.js │ ├── action.js │ ├── cloudevents.js │ ├── cloudstate.js │ ├── command-helper.js │ ├── context-failure.js │ ├── crdt-support.js │ ├── crdt.js │ ├── crdts │ │ ├── flag.js │ │ ├── gcounter.js │ │ ├── gset.js │ │ ├── index.js │ │ ├── lwwregister.js │ │ ├── ormap.js │ │ ├── orset.js │ │ ├── pncounter.js │ │ └── vote.js │ ├── effect-serializer.js │ ├── eventsourced-support.js │ ├── eventsourced.js │ ├── metadata.js │ ├── protobuf-any.js │ └── protobuf-helper.js ├── tck │ ├── .gitignore │ ├── .npmrc │ ├── .nvmrc │ ├── eventsourced.js │ ├── index.js │ ├── package-lock.json │ └── package.json └── test │ ├── crdt-handler-test.js │ ├── crdts │ ├── flag-test.js │ ├── gcounter-test.js │ ├── gset-test.js │ ├── lwwregister-test.js │ ├── ormap-test.js │ ├── orset-test.js │ ├── pncounter-test.js │ └── vote-test.js │ ├── example.proto │ └── protobuf-any-test.js ├── operator ├── cloudstate.yaml ├── deploy │ ├── 01-service-account.yaml │ ├── 02-operator-config.yaml │ ├── 03-role.yaml │ ├── 04-role-binding.yaml │ ├── 05-deployment.yaml │ └── crds │ │ ├── stateful-service-crd.yaml │ │ └── stateful-store-crd.yaml └── src │ └── main │ ├── resources │ ├── application.conf │ ├── logback.xml │ └── reference.conf │ └── scala │ └── io │ └── cloudstate │ └── operator │ ├── GenericStatus.scala │ ├── KnativeRevision.scala │ ├── KnativeRevisionOperatorFactory.scala │ ├── OperatorConfig.scala │ ├── OperatorConstants.scala │ ├── OperatorFactory.scala │ ├── OperatorMain.scala │ ├── OperatorRunner.scala │ ├── ResourceHelper.scala │ ├── StatefulService.scala │ ├── StatefulServiceOperatorFactory.scala │ ├── StatefulStore.scala │ ├── StatefulStoreOperatorFactory.scala │ ├── Validated.scala │ ├── Watcher.scala │ └── stores │ ├── CassandraStoreSupport.scala │ ├── CredentialsHelper.scala │ ├── InMemoryStoreSupport.scala │ ├── PostgresStoreSupport.scala │ └── StatefulStoreSupport.scala ├── project ├── GcpDockerBuildAgentPlugin.scala ├── GraalVMPlugin.scala ├── PublishPlugin.scala ├── VersionPlugin.scala ├── build.properties └── plugins.sbt ├── protoc-installer.sh ├── protocols ├── example │ ├── crdts │ │ └── crdt-example.proto │ ├── shoppingcart │ │ ├── persistence │ │ │ └── domain.proto │ │ └── shoppingcart.proto │ └── valueentity │ │ └── shoppingcart │ │ ├── persistence │ │ └── domain.proto │ │ └── shoppingcart.proto ├── frontend │ ├── cloudstate │ │ ├── entity_key.proto │ │ ├── eventing.proto │ │ └── legacy_entity_key.proto │ └── google │ │ └── api │ │ ├── annotations.proto │ │ ├── http.proto │ │ └── httpbody.proto ├── protocol │ └── cloudstate │ │ ├── action.proto │ │ ├── crdt.proto │ │ ├── entity.proto │ │ ├── event_sourced.proto │ │ └── value_entity.proto └── tck │ └── cloudstate │ └── tck │ └── model │ ├── action.proto │ ├── crdt.proto │ ├── eventlogeventing.proto │ ├── eventsourced.proto │ └── valueentity.proto ├── proxy ├── cassandra │ └── src │ │ ├── graal │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ ├── com.datastax.cassandra │ │ │ │ └── cassandra-driver-core │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.google.guava │ │ │ │ └── guava │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.typesafe.akka │ │ │ │ └── akka-persistence-cassandra │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── io.cloudstate │ │ │ │ └── cloudstate-proxy-cassandra │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── io.netty │ │ │ │ ├── netty-buffer │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── netty-codec │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── netty-common │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── netty-handler │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── netty-transport │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── net.java.openjdk │ │ │ │ └── base │ │ │ │ ├── native-image.properties │ │ │ │ └── reflect-config.json.conf │ │ ├── jni-config.json │ │ ├── proxy-config.json │ │ ├── reflect-config.json │ │ └── resource-config.json │ │ └── main │ │ ├── resources │ │ └── application.conf │ │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── proxy │ │ └── cassandra │ │ └── CassandraProjectionSupport.scala ├── core │ └── src │ │ ├── graal │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ ├── com.google.protobuf │ │ │ │ └── protobuf-java │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.lightbend.akka.discovery │ │ │ │ └── akka-discovery-kubernetes-api │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.lightbend.akka.management │ │ │ │ ├── akka-management-cluster-bootstrap │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── akka-management │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.thesamet.scalapb │ │ │ │ └── scalapb-runtime │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.typesafe.akka │ │ │ │ ├── akka-actor-typed │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-actor │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-cluster-sharding │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-cluster-tools │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-cluster-typed │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-cluster │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-distributed-data │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-http-core │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-http2-support │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-persistence │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-remote │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-slf4j │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── akka-stream │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── dynamic-from-reference-conf │ │ │ │ │ └── native-image.properties │ │ │ │ ├── com.typesafe │ │ │ │ └── ssl-config │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── io.cloudstate │ │ │ │ └── cloudstate-proxy-core │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── io.grpc │ │ │ │ ├── grpc-core │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── grpc-netty-shaded │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── net.java.openjdk │ │ │ │ └── base │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── org.agrona │ │ │ │ └── agrona │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── org.scala-lang │ │ │ │ └── scala-library │ │ │ │ ├── native-image.properties │ │ │ │ └── reflect-config.json.conf │ │ ├── jni-config.json │ │ ├── proxy-config.json │ │ ├── reflect-config.json │ │ └── resource-config.json │ │ ├── main │ │ ├── proto │ │ │ └── cloudstate │ │ │ │ └── proxy │ │ │ │ ├── autoscaler.proto │ │ │ │ ├── crdt_protobufs.proto │ │ │ │ └── statemanager.proto │ │ ├── resources │ │ │ ├── GoogleInternetAuthorityG3.crt │ │ │ ├── cloudstate-common.conf │ │ │ ├── dev-mode.conf │ │ │ ├── in-memory.conf │ │ │ ├── logback.xml │ │ │ ├── no-store.conf │ │ │ ├── reference.conf │ │ │ └── simplelogger.properties │ │ └── scala │ │ │ ├── akka │ │ │ ├── cloudstate │ │ │ │ └── EntityStash.scala │ │ │ └── projection │ │ │ │ └── cloudstate │ │ │ │ └── TestAtLeastOnceFlowProjection.scala │ │ │ └── io │ │ │ └── cloudstate │ │ │ └── proxy │ │ │ ├── CloudStateProxyMain.scala │ │ │ ├── EntityDiscoveryManager.scala │ │ │ ├── FileDescriptorBuilder.scala │ │ │ ├── GrpcWebSupport.scala │ │ │ ├── HttpApi.scala │ │ │ ├── ProtobufAnySerializer.scala │ │ │ ├── Serve.scala │ │ │ ├── UserFunctionRouter.scala │ │ │ ├── UserFunctionTypeSupport.scala │ │ │ ├── action │ │ │ └── ActionProtocolSupportFactory.scala │ │ │ ├── autoscaler │ │ │ ├── Autoscaler.scala │ │ │ ├── KubernetesDeploymentScaler.scala │ │ │ ├── NoAutoscaler.scala │ │ │ └── NoScaler.scala │ │ │ ├── crdt │ │ │ ├── CrdtEntity.scala │ │ │ ├── CrdtEntityManager.scala │ │ │ ├── CrdtSerializers.scala │ │ │ ├── CrdtSupportFactory.scala │ │ │ ├── NodeVector.scala │ │ │ ├── UserFunctionProtocolError.scala │ │ │ ├── Vote.scala │ │ │ └── WireTransformer.scala │ │ │ ├── eventing │ │ │ ├── EventLogEventing.scala │ │ │ ├── EventingManager.scala │ │ │ ├── EventingSupport.scala │ │ │ ├── GooglePubsubEventing.scala │ │ │ └── ProjectionSupport.scala │ │ │ ├── eventsourced │ │ │ ├── EventSourcedEntity.scala │ │ │ ├── EventSourcedSupportFactory.scala │ │ │ ├── InMemJournal.scala │ │ │ └── InMemSnapshotStore.scala │ │ │ ├── protobuf │ │ │ └── Utilities.scala │ │ │ ├── sharding │ │ │ └── DynamicLeastShardAllocationStrategy.scala │ │ │ ├── telemetry │ │ │ ├── CloudstateTelemetry.scala │ │ │ ├── EventSourcedInstrumentation.scala │ │ │ ├── PrometheusEventSourcedInstrumentation.scala │ │ │ └── PrometheusExporter.scala │ │ │ └── valueentity │ │ │ ├── Entity.scala │ │ │ ├── EntitySupportFactory.scala │ │ │ └── store │ │ │ ├── InMemoryStore.scala │ │ │ ├── Repository.scala │ │ │ ├── Store.scala │ │ │ └── package-info.java │ │ └── test │ │ ├── proto │ │ └── cloudstate │ │ │ └── proxy │ │ │ └── test │ │ │ ├── HttpApiTest.proto │ │ │ ├── IllegalHttpConfig0.proto │ │ │ ├── IllegalHttpConfig1.proto │ │ │ ├── IllegalHttpConfig2.proto │ │ │ ├── IllegalHttpConfig3.proto │ │ │ ├── IllegalHttpConfig4.proto │ │ │ ├── IllegalHttpConfig5.proto │ │ │ ├── IllegalHttpConfig6.proto │ │ │ ├── IllegalHttpConfig7.proto │ │ │ ├── IllegalHttpConfig8.proto │ │ │ ├── IllegalHttpConfig9.proto │ │ │ └── thing.proto │ │ ├── resources │ │ ├── googlepubsub.conf │ │ └── test-in-memory.conf │ │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── proxy │ │ ├── HttpApiSpec.scala │ │ ├── PathTemplateParserSpec.scala │ │ ├── TestProxy.scala │ │ ├── autoscaler │ │ └── AutoscalerSpec.scala │ │ ├── crdt │ │ ├── AbstractCrdtEntitySpec.scala │ │ ├── CrdtEntitySpec.scala │ │ ├── FlagCrdtEntitySpec.scala │ │ ├── GCounterCrdtEntitySpec.scala │ │ ├── GSetCrdtEntitySpec.scala │ │ ├── LWWRegisterCrdtEntitySpec.scala │ │ ├── ORMapCrdtEntitySpec.scala │ │ ├── ORSetCrdtEntitySpec.scala │ │ └── PNCounterCrdtEntitySpec.scala │ │ ├── eventsourced │ │ ├── EventSourcedRestartSpec.scala │ │ └── ExceptionHandlingSpec.scala │ │ ├── telemetry │ │ ├── AbstractTelemetrySpec.scala │ │ ├── CloudstateTelemetrySpec.scala │ │ └── EventSourcedInstrumentationSpec.scala │ │ └── valueentity │ │ ├── DatabaseExceptionHandlingSpec.scala │ │ ├── EntityPassivateSpec.scala │ │ └── ExceptionHandlingSpec.scala ├── jdbc │ └── src │ │ ├── main │ │ ├── resources │ │ │ ├── jdbc-common.conf │ │ │ └── reference.conf │ │ └── scala │ │ │ └── io │ │ │ └── cloudstate │ │ │ └── proxy │ │ │ ├── jdbc │ │ │ ├── CloudStateJdbcProxyMain.scala │ │ │ ├── SlickCreateTables.scala │ │ │ ├── SlickEnsureTablesExistReadyCheck.scala │ │ │ └── SlickProjectionSupport.scala │ │ │ └── valueentity │ │ │ └── store │ │ │ └── jdbc │ │ │ ├── JdbcConfig.scala │ │ │ ├── JdbcEntityQueries.scala │ │ │ ├── JdbcEntityTable.scala │ │ │ └── JdbcStore.scala │ │ └── test │ │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── proxy │ │ └── valueentity │ │ └── store │ │ └── jdbc │ │ └── JdbcConfigSpec.scala ├── postgres │ └── src │ │ ├── graal │ │ ├── META-INF │ │ │ └── native-image │ │ │ │ ├── com.github.dnvriend │ │ │ │ └── akka-persistence-jdbc │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.typesafe.slick │ │ │ │ ├── slick-hikaricp │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── slick │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── com.zaxxer │ │ │ │ └── HikariCP │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── io.cloudstate │ │ │ │ └── cloudstate-proxy-jdbc │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ ├── net.java.openjdk │ │ │ │ └── base │ │ │ │ │ ├── native-image.properties │ │ │ │ │ └── reflect-config.json.conf │ │ │ │ └── org.postgresql │ │ │ │ └── postgresql │ │ │ │ ├── native-image.properties │ │ │ │ └── reflect-config.json.conf │ │ ├── jni-config.json │ │ ├── proxy-config.json │ │ ├── reflect-config.json │ │ └── resource-config.json │ │ └── main │ │ └── resources │ │ └── application.conf ├── proxy-tests │ └── src │ │ └── test │ │ ├── resources │ │ └── logback-test.xml │ │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── proxy │ │ ├── eventing │ │ └── GooglePubsubSpec.scala │ │ └── stress │ │ └── CrdtStressSpec.scala └── spanner │ └── src │ ├── graal │ ├── jni-config.json │ ├── proxy-config.json │ ├── reflect-config.json │ └── resource-config.json │ ├── main │ ├── resources │ │ └── application.conf │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── proxy │ │ └── spanner │ │ ├── CloudstateSpannerProxyMain.scala │ │ ├── Schema.scala │ │ └── SchemaCheck.scala │ └── test │ ├── resources │ └── application.conf │ └── scala │ └── io │ └── cloudstate │ └── proxy │ └── spanner │ └── SchemaCheckTests.scala ├── samples ├── README.md ├── akka-client │ └── src │ │ └── main │ │ ├── resources │ │ └── application.conf │ │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── samples │ │ ├── CrdtsClient.scala │ │ └── ShoppingCartClient.scala ├── java-eventsourced-shopping-cart │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── cloudstate │ │ │ └── samples │ │ │ └── eventsourced │ │ │ └── shoppingcart │ │ │ ├── Main.java │ │ │ └── ShoppingCartEntity.java │ │ └── resources │ │ ├── application.conf │ │ └── simplelogger.properties ├── java-pingpong │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── cloudstate │ │ │ └── samples │ │ │ └── pingpong │ │ │ ├── Main.java │ │ │ └── PingPongEntity.java │ │ ├── protos │ │ └── pingpong │ │ │ └── pingpong.proto │ │ └── resources │ │ ├── application.conf │ │ └── simplelogger.properties ├── java-shopping-cart │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── cloudstate │ │ │ └── samples │ │ │ └── shoppingcart │ │ │ ├── Main.java │ │ │ └── ShoppingCartEntity.java │ │ └── resources │ │ ├── application.conf │ │ └── simplelogger.properties ├── js-crdts │ ├── .npmrc │ ├── .nvmrc │ ├── build │ │ └── config.gypi │ ├── crdt-example.js │ ├── index.js │ ├── package-lock.json │ ├── package.json │ ├── presence-client.js │ ├── stateful-service.yaml │ └── user-function.desc ├── js-shopping-cart-load-generator │ ├── load-generator.yaml │ └── src │ │ └── main │ │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── loadgenerator │ │ └── GenerateLoad.scala └── js-shopping-cart │ ├── .npmrc │ ├── .nvmrc │ ├── cassandra-store.yaml │ ├── in-memory-store.yaml │ ├── index.js │ ├── istio.yaml │ ├── js-shopping-cart.yaml │ ├── knative.yaml │ ├── package-lock.json │ ├── package.json │ ├── postgres-store.yaml │ ├── shoppingcart.js │ ├── test │ └── test.js │ └── user-function.desc ├── tck └── src │ ├── it │ ├── resources │ │ ├── application.conf │ │ ├── native-image.conf │ │ └── reference.conf │ └── scala │ │ └── io │ │ └── cloudstate │ │ └── tck │ │ ├── TCK.scala │ │ ├── TckConfiguration.scala │ │ └── TckProcesses.scala │ └── main │ ├── resources │ └── reference.conf │ └── scala │ └── io │ └── cloudstate │ └── tck │ ├── ActionTCK.scala │ ├── CloudstateTCK.scala │ ├── CrdtEntityTCK.scala │ ├── EntityTCK.scala │ ├── EventSourcedEntityTCK.scala │ ├── EventingTCK.scala │ ├── ProxyTCK.scala │ └── TCKSpec.scala ├── testkit └── src │ └── main │ └── scala │ └── io │ └── cloudstate │ └── testkit │ ├── InterceptService.scala │ ├── Sockets.scala │ ├── TestClient.scala │ ├── TestProtocol.scala │ ├── TestService.scala │ ├── action │ ├── ActionMessages.scala │ ├── InterceptActionService.scala │ └── TestActionProtocol.scala │ ├── crdt │ ├── CrdtMessages.scala │ ├── InterceptCrdtService.scala │ └── TestCrdtProtocol.scala │ ├── discovery │ ├── InterceptEntityDiscovery.scala │ └── TestEntityDiscoveryService.scala │ ├── entity │ └── EntityMessages.scala │ ├── eventsourced │ ├── EventSourcedMessages.scala │ ├── InterceptEventSourcedService.scala │ ├── TestEventSourcedProtocol.scala │ └── TestEventSourcedService.scala │ ├── http │ └── TestHttpClient.scala │ ├── reflection │ └── TestServerReflectionClient.scala │ └── valueentity │ ├── InterceptValueEntityService.scala │ ├── TestValueEntityProtocol.scala │ ├── TestValueEntityService.scala │ └── ValueEntityMessages.scala └── travis ├── jvmopts └── upload-release-assets.sh /.devcontainer/build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o nounset 4 | set -o errexit 5 | set -o pipefail 6 | 7 | CMD=${1:-image} 8 | docker build . -t cloudstateio/cloudstate-devcontainer:latest 9 | if [ "$CMD" == "push" ]; then 10 | docker push cloudstateio/cloudstate-devcontainer:latest 11 | fi 12 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Scala", 3 | "dockerFile": "Dockerfile", 4 | "image": "cloudstateio/cloudstate-devcontainer:latest", 5 | "settings": { 6 | "terminal.integrated.shell.linux": "/bin/bash", 7 | "[scala]": { 8 | "editor.tabSize": 2, 9 | "editor.insertSpaces": true 10 | } 11 | }, 12 | "extensions": [ 13 | "scala-lang.scala", 14 | "zxh404.vscode-proto3" 15 | ], 16 | "runArgs": [ 17 | "-v", 18 | "/var/run/docker.sock:/var/run/docker.sock" 19 | ], 20 | "remoteUser": "vscode" 21 | } -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | **/node_modules 2 | **/target 3 | node-support/protoc 4 | .idea 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *# 2 | *.md= 3 | *.log 4 | *.orig 5 | *.jfr 6 | *.iml 7 | *.ipr 8 | *.iws 9 | *.pyc 10 | *.vim 11 | */project/boot 12 | */project/build/target 13 | *~ 14 | .#* 15 | .*.swp 16 | .bloop 17 | .DS_Store 18 | .cache 19 | .classpath 20 | .codefellow 21 | .ensime* 22 | .eprj 23 | .history 24 | .idea 25 | .ideaq 26 | .manager 27 | .metals 28 | .multi-jvm 29 | .nyc_output 30 | etags 31 | lib_managed 32 | logs 33 | manifest.mf 34 | node_modules 35 | null 36 | null/* 37 | project/plugins/project 38 | src_managed 39 | storage 40 | tags 41 | target 42 | target-sbt 43 | -------------------------------------------------------------------------------- /.sbtopts: -------------------------------------------------------------------------------- 1 | -Dsbt.classloader.close=false 2 | -J-XX:+UseCompressedOops 3 | -J-XX:+CMSClassUnloadingEnabled 4 | -J-XX:MaxMetaspaceSize=384m -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | version = 2.0.1 2 | 3 | style = defaultWithAlign 4 | 5 | align.tokens = [off] 6 | align.openParenDefnSite = true 7 | align.openParenCallSite = true 8 | danglingParentheses = true 9 | docstrings = JavaDoc 10 | indentOperator = spray 11 | maxColumn = 120 12 | rewrite.rules = [RedundantBraces, RedundantParens, SortImports] 13 | unindentTopLevelOperators = true -------------------------------------------------------------------------------- /Dockerfile.js-crdts: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | # Copy and install deps. This is done as a separate step as an optimization, so changes to the programs files 4 | # don't require the npm install to be redone 5 | RUN mkdir -p /opt/samples/js-crdts 6 | RUN mkdir -p /opt/protocols/example 7 | COPY node-support /opt/node-support 8 | COPY samples/js-crdts/package.json /opt/samples/js-crdts/ 9 | RUN cd /opt/node-support && npm install && cd /opt/samples/js-crdts && npm install 10 | 11 | # Now copy the entire app 12 | COPY samples/js-crdts /opt/samples/js-crdts 13 | COPY protocols/example /opt/protocols/example 14 | WORKDIR /opt/samples/js-crdts 15 | RUN npm run prestart 16 | 17 | # run 18 | EXPOSE 8080 19 | ENV DEBUG=cloudstate* 20 | ENTRYPOINT ["npm", "run", "start-no-prestart"] 21 | -------------------------------------------------------------------------------- /Dockerfile.js-shopping-cart: -------------------------------------------------------------------------------- 1 | FROM node:12 2 | 3 | # Copy and install deps. This is done as a separate step as an optimization, so changes to the programs files 4 | # don't require the npm install to be redone 5 | RUN mkdir -p /opt/samples/js-shopping-cart 6 | RUN mkdir -p /opt/protocols/example 7 | COPY node-support /opt/node-support 8 | COPY samples/js-shopping-cart/package.json /opt/samples/js-shopping-cart/ 9 | RUN cd /opt/node-support && npm install && cd /opt/samples/js-shopping-cart && npm install 10 | 11 | # Now copy the entire app 12 | COPY samples/js-shopping-cart /opt/samples/js-shopping-cart 13 | COPY protocols/example /opt/protocols/example 14 | WORKDIR /opt/samples/js-shopping-cart 15 | RUN npm run prestart 16 | 17 | # run 18 | EXPOSE 8080 19 | CMD ["npm", "run", "start-no-prestart"] 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Cloudstate is no longer actively developed** 2 | 3 | Cloudstate was an open source protocol and reference implementation exploring ideas for _stateful serverless_, and was originally developed by [Lightbend]. 4 | 5 | The project is no longer active, since 2021. An open source alternative is [Eigr]. 6 | 7 | A continuation of the ideas can be found in Lightbend's platform-as-a-service [Akka Serverless]. 8 | 9 | [Lightbend]: https://www.lightbend.com 10 | [Eigr]: https://eigr.io 11 | [Akka Serverless]: https://www.lightbend.com/akka-serverless 12 | -------------------------------------------------------------------------------- /bin/install-cassandra.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Install single-node Cassandra for testing, using helm 4 | 5 | set -e 6 | 7 | echo 8 | echo "=== Installing Cassandra ===" 9 | echo 10 | 11 | readonly cassandra_chart_version="5.6.1" 12 | 13 | # install cassandra via helm chart 14 | helm repo add bitnami https://charts.bitnami.com/bitnami 15 | helm install cassandra bitnami/cassandra --version $cassandra_chart_version --set persistence.enabled=false 16 | 17 | # can only kubectl wait when the resource already exists 18 | echo 19 | echo "Waiting for cassandra to be created..." 20 | attempts=10 21 | until kubectl get pod cassandra-0 &> /dev/null || [ $attempts -eq 0 ] ; do 22 | ((attempts--)) 23 | sleep 1 24 | done 25 | kubectl get pod cassandra-0 26 | 27 | # wait for cassandra pod to be ready (can take a while) 28 | echo 29 | echo "Waiting for cassandra to be ready..." 30 | if ! kubectl wait --for=condition=ready --timeout=10m pod/cassandra-0 ; then 31 | kubectl describe statefulset cassandra 32 | kubectl logs cassandra-0 33 | exit 1 34 | fi 35 | kubectl get statefulset cassandra 36 | 37 | CASSANDRA_PASSWORD=$(kubectl get secret --namespace default cassandra -o jsonpath="{.data.cassandra-password}" | base64 --decode) 38 | kubectl create secret generic cassandra-credentials \ 39 | --from-literal=username=cassandra --from-literal=password="$CASSANDRA_PASSWORD" 40 | -------------------------------------------------------------------------------- /cloudstate-operator/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | bin 9 | 10 | # Test binary, build with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | 16 | # Kubernetes Generated files - skip generated files, except for vendored files 17 | 18 | !vendor/**/zz_generated.* 19 | 20 | # editor and IDE paraphernalia 21 | .idea 22 | *.swp 23 | *.swo 24 | *~ 25 | vendor 26 | -------------------------------------------------------------------------------- /cloudstate-operator/Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the manager binary 2 | FROM golang:1.13.15 as builder 3 | 4 | WORKDIR /workspace 5 | # Copy the Go Modules manifests 6 | COPY go.mod go.mod 7 | COPY go.sum go.sum 8 | 9 | # Copy the dependencies from vendor 10 | COPY vendor/ vendor/ 11 | 12 | # Copy the go source 13 | COPY cmd/ cmd/ 14 | COPY pkg/ pkg/ 15 | COPY internal/ internal/ 16 | 17 | # Build 18 | RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -mod vendor -a -o manager cmd/main.go 19 | 20 | # Use distroless as minimal base image to package the manager binary 21 | # Refer to https://github.com/GoogleContainerTools/distroless for more details 22 | FROM gcr.io/distroless/static:nonroot 23 | WORKDIR / 24 | COPY --from=builder /workspace/manager . 25 | USER nonroot:nonroot 26 | 27 | ENTRYPOINT ["/manager"] 28 | -------------------------------------------------------------------------------- /cloudstate-operator/PROJECT: -------------------------------------------------------------------------------- 1 | version: "2" 2 | domain: io 3 | repo: github.com/cloudstateio/cloudstate/cloudstate-operator 4 | resources: 5 | - group: cloudstate 6 | version: v1alpha1 7 | kind: StatefulStore 8 | - group: cloudstate 9 | version: v1alpha1 10 | kind: StatefulService 11 | -------------------------------------------------------------------------------- /cloudstate-operator/config/certmanager/certificate.yaml: -------------------------------------------------------------------------------- 1 | # The following manifests contain a self-signed issuer CR and a certificate CR. 2 | # More document can be found at https://docs.cert-manager.io 3 | # WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes 4 | apiVersion: cert-manager.io/v1alpha2 5 | kind: Issuer 6 | metadata: 7 | name: selfsigned-issuer 8 | namespace: system 9 | spec: 10 | selfSigned: {} 11 | --- 12 | apiVersion: cert-manager.io/v1alpha2 13 | kind: Certificate 14 | metadata: 15 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 16 | namespace: system 17 | spec: 18 | # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize 19 | dnsNames: 20 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc 21 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local 22 | issuerRef: 23 | kind: Issuer 24 | name: selfsigned-issuer 25 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize 26 | -------------------------------------------------------------------------------- /cloudstate-operator/config/certmanager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - certificate.yaml 3 | 4 | configurations: 5 | - kustomizeconfig.yaml 6 | -------------------------------------------------------------------------------- /cloudstate-operator/config/certmanager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is for teaching kustomize how to update name ref and var substitution 2 | nameReference: 3 | - kind: Issuer 4 | group: cert-manager.io 5 | fieldSpecs: 6 | - kind: Certificate 7 | group: cert-manager.io 8 | path: spec/issuerRef/name 9 | 10 | varReference: 11 | - kind: Certificate 12 | group: cert-manager.io 13 | path: spec/commonName 14 | - kind: Certificate 15 | group: cert-manager.io 16 | path: spec/dnsNames 17 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This file is for teaching kustomize how to substitute name and namespace reference in CRD 2 | nameReference: 3 | - kind: Service 4 | version: v1 5 | fieldSpecs: 6 | - kind: CustomResourceDefinition 7 | group: apiextensions.k8s.io 8 | path: spec/conversion/webhookClientConfig/service/name 9 | 10 | namespace: 11 | - kind: CustomResourceDefinition 12 | group: apiextensions.k8s.io 13 | path: spec/conversion/webhookClientConfig/service/namespace 14 | create: false 15 | 16 | varReference: 17 | - path: metadata/annotations 18 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/patches/cainjection_in_routes.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: routes.cloudstate.io 9 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/patches/cainjection_in_statefulservices.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: statefulservices.cloudstate.io 9 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/patches/cainjection_in_statefulstores.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: statefulstores.cloudstate.io 9 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/patches/fix-container-port-protocol-patch.yaml: -------------------------------------------------------------------------------- 1 | - op: "replace" 2 | path: "/spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/containers/items/properties/ports/items/required" 3 | value: [ "containerPort", "protocol"] 4 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/patches/webhook_in_routes.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: routes.cloudstate.io 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/patches/webhook_in_statefulservices.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: statefulservices.cloudstate.io 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /cloudstate-operator/config/crd/patches/webhook_in_statefulstores.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: statefulstores.cloudstate.io 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /cloudstate-operator/config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the controller manager, 2 | # it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.4.1 14 | args: 15 | - "--secure-listen-address=0.0.0.0:8443" 16 | - "--upstream=http://127.0.0.1:8080/" 17 | - "--logtostderr=true" 18 | - "--v=10" 19 | ports: 20 | - containerPort: 8443 21 | name: https 22 | - name: manager 23 | args: 24 | - "--metrics-addr=127.0.0.1:8080" 25 | - "--enable-leader-election" 26 | -------------------------------------------------------------------------------- /cloudstate-operator/config/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | ports: 12 | - containerPort: 9443 13 | name: webhook-server 14 | protocol: TCP 15 | volumeMounts: 16 | - mountPath: /tmp/k8s-webhook-server/serving-certs 17 | name: cert 18 | readOnly: true 19 | volumes: 20 | - name: cert 21 | secret: 22 | defaultMode: 420 23 | secretName: webhook-server-cert 24 | -------------------------------------------------------------------------------- /cloudstate-operator/config/default/webhookcainjection_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch add annotation to admission webhook config and 2 | # the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. 3 | apiVersion: admissionregistration.k8s.io/v1beta1 4 | kind: MutatingWebhookConfiguration 5 | metadata: 6 | name: cloudstate-operator-webhook 7 | annotations: 8 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 9 | -------------------------------------------------------------------------------- /cloudstate-operator/config/manager/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: config 5 | data: 6 | config.yaml: | 7 | noStore: 8 | image: cloudstateio/cloudstate-proxy-core:latest 9 | # args: 10 | # - "-Dconfig.resource=no-store.conf" 11 | inMemory: 12 | image: cloudstateio/cloudstate-proxy-core:latest 13 | # args: 14 | # - "-Dconfig.resource=in-memory.conf" 15 | postgres: 16 | image: cloudstateio/cloudstate-proxy-postgres:latest 17 | cassandra: 18 | image: cloudstateio/cloudstate-proxy-cassandra:latest 19 | # sidecarMetrics: 20 | # port: 9099 -------------------------------------------------------------------------------- /cloudstate-operator/config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - configmap.yaml 3 | - manager.yaml 4 | -------------------------------------------------------------------------------- /cloudstate-operator/config/native-image/cloudstate-config-patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | namespace: cloudstate-system 5 | name: cloudstate-config 6 | data: 7 | config.yaml: | 8 | noStore: 9 | image: cloudstateio/cloudstate-proxy-native-core:latest 10 | # args: 11 | # - "-Dconfig.resource=no-store.conf" 12 | inMemory: 13 | image: cloudstateio/cloudstate-proxy-native-core:latest 14 | # args: 15 | # - "-Dconfig.resource=in-memory.conf" 16 | postgres: 17 | image: cloudstateio/cloudstate-proxy-native-postgres:latest 18 | cassandra: 19 | image: cloudstateio/cloudstate-proxy-native-cassandra:latest 20 | -------------------------------------------------------------------------------- /cloudstate-operator/config/native-image/kustomization.yaml: -------------------------------------------------------------------------------- 1 | bases: 2 | - ../default 3 | 4 | patchesStrategicMerge: 5 | - cloudstate-config-patch.yaml 6 | -------------------------------------------------------------------------------- /cloudstate-operator/config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | -------------------------------------------------------------------------------- /cloudstate-operator/config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | 2 | # Prometheus Monitor Service (Metrics) 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | labels: 7 | control-plane: controller-manager 8 | name: controller-manager-metrics-monitor 9 | namespace: system 10 | spec: 11 | endpoints: 12 | - path: /metrics 13 | port: https 14 | selector: 15 | control-plane: controller-manager 16 | -------------------------------------------------------------------------------- /cloudstate-operator/config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: proxy-role 5 | rules: 6 | - apiGroups: ["authentication.k8s.io"] 7 | resources: 8 | - tokenreviews 9 | verbs: ["create"] 10 | - apiGroups: ["authorization.k8s.io"] 11 | resources: 12 | - subjectaccessreviews 13 | verbs: ["create"] 14 | -------------------------------------------------------------------------------- /cloudstate-operator/config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: proxy-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: proxy-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /cloudstate-operator/config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | control-plane: controller-manager 6 | name: controller-manager-metrics-service 7 | namespace: system 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | targetPort: https 13 | selector: 14 | control-plane: controller-manager 15 | -------------------------------------------------------------------------------- /cloudstate-operator/config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - role.yaml 3 | - role_binding.yaml 4 | - leader_election_role.yaml 5 | - leader_election_role_binding.yaml 6 | # Comment the following 3 lines if you want to disable 7 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 8 | # which protects your /metrics endpoint. 9 | - auth_proxy_service.yaml 10 | - auth_proxy_role.yaml 11 | - auth_proxy_role_binding.yaml 12 | -------------------------------------------------------------------------------- /cloudstate-operator/config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: leader-election-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - "" 21 | resources: 22 | - configmaps/status 23 | verbs: 24 | - get 25 | - update 26 | - patch 27 | - apiGroups: 28 | - "" 29 | resources: 30 | - events 31 | verbs: 32 | - create 33 | -------------------------------------------------------------------------------- /cloudstate-operator/config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /cloudstate-operator/config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: manager-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: manager-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /cloudstate-operator/config/samples/cloudstate_v1alpha1_route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cloudstate.io/v1alpha1 2 | kind: Route 3 | metadata: 4 | name: route-sample 5 | spec: 6 | # Add fields here 7 | foo: bar 8 | -------------------------------------------------------------------------------- /cloudstate-operator/config/samples/cloudstate_v1alpha1_statefulservice.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cloudstate.io/v1alpha1 2 | kind: StatefulService 3 | metadata: 4 | name: statefulservice-sample 5 | spec: 6 | containers: 7 | - image: cloudstateio/samples-js-chat-presence:latest 8 | name: "presence-app" 9 | -------------------------------------------------------------------------------- /cloudstate-operator/config/samples/cloudstate_v1alpha1_statefulstore.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cloudstate.io/v1alpha1 2 | kind: StatefulStore 3 | metadata: 4 | name: statefulstore-sample 5 | spec: 6 | # Add fields here 7 | foo: bar 8 | -------------------------------------------------------------------------------- /cloudstate-operator/config/webhook/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manifests.yaml 3 | - service.yaml 4 | 5 | configurations: 6 | - kustomizeconfig.yaml 7 | -------------------------------------------------------------------------------- /cloudstate-operator/config/webhook/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # the following config is for teaching kustomize where to look at when substituting vars. 2 | # It requires kustomize v2.1.0 or newer to work properly. 3 | nameReference: 4 | - kind: Service 5 | version: v1 6 | fieldSpecs: 7 | - kind: MutatingWebhookConfiguration 8 | group: admissionregistration.k8s.io 9 | path: webhooks/clientConfig/service/name 10 | - kind: ValidatingWebhookConfiguration 11 | group: admissionregistration.k8s.io 12 | path: webhooks/clientConfig/service/name 13 | 14 | namespace: 15 | - kind: MutatingWebhookConfiguration 16 | group: admissionregistration.k8s.io 17 | path: webhooks/clientConfig/service/namespace 18 | create: true 19 | - kind: ValidatingWebhookConfiguration 20 | group: admissionregistration.k8s.io 21 | path: webhooks/clientConfig/service/namespace 22 | create: true 23 | 24 | varReference: 25 | - path: metadata/annotations 26 | -------------------------------------------------------------------------------- /cloudstate-operator/config/webhook/manifests.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: admissionregistration.k8s.io/v1beta1 2 | kind: MutatingWebhookConfiguration 3 | metadata: 4 | creationTimestamp: null 5 | name: cloudstate-operator-webhook 6 | webhooks: 7 | - clientConfig: 8 | caBundle: Cg== 9 | service: 10 | name: webhook-service 11 | namespace: system 12 | path: /inject-v1-pod 13 | failurePolicy: Fail 14 | name: mpod.kb.io 15 | objectSelector: 16 | matchExpressions: 17 | - key: manager.cloudstate.io/ignore 18 | operator: DoesNotExist 19 | rules: 20 | - apiGroups: 21 | - "" 22 | apiVersions: 23 | - v1 24 | operations: 25 | - CREATE 26 | - UPDATE 27 | resources: 28 | - pods -------------------------------------------------------------------------------- /cloudstate-operator/config/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: webhook-service 6 | namespace: system 7 | spec: 8 | ports: 9 | - port: 443 10 | targetPort: 9443 11 | selector: 12 | control-plane: controller-manager 13 | -------------------------------------------------------------------------------- /cloudstate-operator/hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ -------------------------------------------------------------------------------- /cloudstate-operator/pkg/config/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | // TODO: describe package here. 16 | package config 17 | -------------------------------------------------------------------------------- /cloudstate-operator/pkg/controllers/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | // TODO: describe package here. 16 | package controllers 17 | -------------------------------------------------------------------------------- /cloudstate-operator/pkg/listeners/statefulservice_listener.go: -------------------------------------------------------------------------------- 1 | package listeners 2 | 3 | import ( 4 | "context" 5 | cloudstate "github.com/cloudstateio/cloudstate/cloudstate-operator/pkg/apis/v1alpha1" 6 | appsv1 "k8s.io/api/apps/v1" 7 | ) 8 | 9 | type StatefulServiceListener interface { 10 | DeploymentCreated(ctx context.Context, service *cloudstate.StatefulService, created *appsv1.Deployment) error 11 | DeploymentUpdated(ctx context.Context, service *cloudstate.StatefulService, old *appsv1.Deployment, new *appsv1.Deployment) error 12 | } 13 | 14 | type NullStatefulServiceListener struct { 15 | } 16 | 17 | var _ StatefulServiceListener = (*NullStatefulServiceListener)(nil) 18 | 19 | func (n *NullStatefulServiceListener) DeploymentCreated(ctx context.Context, service *cloudstate.StatefulService, created *appsv1.Deployment) error { 20 | return nil 21 | } 22 | 23 | func (n *NullStatefulServiceListener) DeploymentUpdated(ctx context.Context, service *cloudstate.StatefulService, old *appsv1.Deployment, new *appsv1.Deployment) error { 24 | return nil 25 | } 26 | -------------------------------------------------------------------------------- /cloudstate-operator/pkg/stores/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Licensed under the Apache License, Version 2.0 (the "License"); 3 | you may not use this file except in compliance with the License. 4 | You may obtain a copy of the License at 5 | 6 | http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | Unless required by applicable law or agreed to in writing, software 9 | distributed under the License is distributed on an "AS IS" BASIS, 10 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | See the License for the specific language governing permissions and 12 | limitations under the License. 13 | */ 14 | 15 | // TODO: describe package here. 16 | package stores 17 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | /.cache/ 2 | /.deploy/ 3 | /build/ 4 | -------------------------------------------------------------------------------- /docs/README.adoc: -------------------------------------------------------------------------------- 1 | = Cloudstate documentation 2 | 3 | Build the docs using the Makefile: 4 | 5 | .... 6 | make build 7 | .... 8 | 9 | Open the docs index page: 10 | 11 | .... 12 | open build/site/index.html 13 | .... 14 | 15 | Or build in author mode: 16 | 17 | .... 18 | make build-author-mode 19 | .... 20 | -------------------------------------------------------------------------------- /docs/config/validate-links.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ 3 | { "pattern": "^https?://localhost" }, 4 | { "pattern": "^https?://\\d+\\." }, 5 | { "pattern": "^https://github\\.com/cloudstateio/cloudstate/releases/download" }, 6 | { "pattern": "^https://raw\\.githubusercontent\\.com/cloudstateio/cloudstate" } 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /docs/src/antora.yml: -------------------------------------------------------------------------------- 1 | name: "" 2 | version: master 3 | title: "Cloudstate" 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | - modules/concepts/nav.adoc 7 | - modules/develop/nav.adoc 8 | - modules/dart/nav.adoc 9 | - modules/go/nav.adoc 10 | - modules/java/nav.adoc 11 | - modules/javascript/nav.adoc 12 | - modules/kotlin/nav.adoc 13 | - modules/python/nav.adoc 14 | - modules/springboot/nav.adoc 15 | - modules/dotnet/nav.adoc 16 | - modules/deploy/nav.adoc 17 | - modules/contribute/nav.adoc 18 | -------------------------------------------------------------------------------- /docs/src/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Introduction] 2 | ** xref:stateless-limitations.adoc[Current limitations of Serverless platforms] 3 | ** xref:crud-limitations.adoc[Rethinking CRUD] 4 | ** xref:cloudstate-solution.adoc[The Cloudstate solution] 5 | ** xref:working.adoc[Working with Cloudstate] 6 | ** xref:examples.adoc[Example Applications] 7 | -------------------------------------------------------------------------------- /docs/src/modules/ROOT/pages/cloudstate-solution.adoc: -------------------------------------------------------------------------------- 1 | = The Cloudstate solution 2 | 3 | include::ROOT:partial$cloudstate-solution.adoc[] 4 | 5 | -------------------------------------------------------------------------------- /docs/src/modules/ROOT/pages/crud-limitations.adoc: -------------------------------------------------------------------------------- 1 | = Rethinking CRUD 2 | 3 | include::ROOT:partial$crud-limitations.adoc[] 4 | 5 | -------------------------------------------------------------------------------- /docs/src/modules/ROOT/pages/examples.adoc: -------------------------------------------------------------------------------- 1 | = Example applications 2 | 3 | include::ROOT:partial$examples.adoc[] 4 | -------------------------------------------------------------------------------- /docs/src/modules/ROOT/pages/stateless-limitations.adoc: -------------------------------------------------------------------------------- 1 | = Current limitations of Serverless platforms 2 | 3 | include::ROOT:partial$stateless-limitations.adoc[] 4 | 5 | -------------------------------------------------------------------------------- /docs/src/modules/ROOT/pages/working.adoc: -------------------------------------------------------------------------------- 1 | = Working with Cloudstate 2 | 3 | include::ROOT:partial$working.adoc[] 4 | -------------------------------------------------------------------------------- /docs/src/modules/ROOT/partials/include.adoc: -------------------------------------------------------------------------------- 1 | :minimum-istio-version: 1.2.0 2 | :minimum-kubernetes-version: 1.11 3 | -------------------------------------------------------------------------------- /docs/src/modules/contribute/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Contributing to the project] 2 | ** xref:architecture.adoc[Architecture] 3 | ** xref:getting-started.adoc[Getting started] 4 | ** xref:build-native.adoc[Building native images] 5 | ** xref:serialization.adoc[Serialization conventions] 6 | ** xref:language-support.adoc[Language support] 7 | ** xref:knative-integration.adoc[Knative integration] 8 | ** xref:graalvm-integration.adoc[GraalVM integration] 9 | ** xref:testing.adoc[Testing] 10 | -------------------------------------------------------------------------------- /docs/src/modules/contribute/pages/architecture.adoc: -------------------------------------------------------------------------------- 1 | = Architecture 2 | 3 | include::ROOT:partial$architecture.adoc[] 4 | -------------------------------------------------------------------------------- /docs/src/modules/deploy/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Deploying to production systems] 2 | ** xref:install-production.adoc[Setting up a production cluster] 3 | ** xref:deploying.adoc[Deploying stateful services] 4 | ** xref:stateful-stores.adoc[Stateful stores] 5 | *** xref:cassandra.adoc[Cassandra] 6 | *** xref:postgresql.adoc[PostgresSQL] 7 | *** xref:inmemory.adoc[In memory store] 8 | ** xref:monitoring.adoc[Monitoring] 9 | ** xref:autoscaling.adoc[Autoscaling] 10 | ** xref:security.adoc[Security] 11 | -------------------------------------------------------------------------------- /docs/src/modules/deploy/pages/autoscaling.adoc: -------------------------------------------------------------------------------- 1 | = Autoscaling 2 | 3 | * Explain how to integrate with the Kubernetes HPA 4 | * Explain how to use Cloudstate's own autoscaler 5 | * Talk about scaling to zero (not currently possible) 6 | -------------------------------------------------------------------------------- /docs/src/modules/deploy/pages/cassandra.adoc: -------------------------------------------------------------------------------- 1 | = Apache Cassandra 2 | 3 | * Explain how to configure a Cassandra store 4 | * Give some quick links to installing Cassandra in different environments 5 | -------------------------------------------------------------------------------- /docs/src/modules/deploy/pages/inmemory.adoc: -------------------------------------------------------------------------------- 1 | = In memory 2 | 3 | * Explain that an in memory store is available. 4 | * Point out that it makes no sense whatsoever to use it in production. 5 | 6 | == What InMemory is Good For 7 | An in-memory store for state is useful for a number of things: Running locally and testing (especially end-to-end or functional testing) for example. It is, however 8 | not useful in an actual production service. 9 | 10 | The InMemory store does not *persist* your data between invokations - it only emulates persistence by keeping the events temporarily in RAM. When the executable terminates, 11 | your data is gone. 12 | 13 | This is basically *never* what you want in production. So why have it? 14 | 15 | As we hinted above, InMemory is valuable for running locally. There is no need do so some things, and it puts far less load on your local system. 16 | -------------------------------------------------------------------------------- /docs/src/modules/deploy/pages/monitoring.adoc: -------------------------------------------------------------------------------- 1 | = Monitoring 2 | 3 | * Explain how to monitor external communication with Istio 4 | * Explain how to collect metrics from Cloudstate (it doesn't currently produce any) 5 | * Explain how to understand those metrics 6 | -------------------------------------------------------------------------------- /docs/src/modules/deploy/pages/postgresql.adoc: -------------------------------------------------------------------------------- 1 | = PostgreSQL 2 | 3 | * Explain how to configure a PostgreSQL store. 4 | * Explain how to configure credentials. 5 | * Give some quick links to installing PostgreSQL in different environments. 6 | -------------------------------------------------------------------------------- /docs/src/modules/deploy/pages/security.adoc: -------------------------------------------------------------------------------- 1 | = Security 2 | 3 | * Explain how to use Istio to enable TLS for communications 4 | -------------------------------------------------------------------------------- /docs/src/modules/develop/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Developing Cloudstate services] 2 | ** xref:prerequisites.adoc[Prerequisites] 3 | ** xref:install.adoc[Installing Cloudstate] 4 | ** xref:gke.adoc[Run on GKE] 5 | ** xref:examples.adoc[Available Cloudstate examples] 6 | ** xref:tutorial.adoc[The shopping cart tutorial] 7 | -------------------------------------------------------------------------------- /docs/src/modules/develop/pages/examples.adoc: -------------------------------------------------------------------------------- 1 | = Available Cloudstate examples 2 | 3 | This page will have a matrix of examples and links to the repos. 4 | -------------------------------------------------------------------------------- /docs/src/modules/develop/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Developing Cloudstate services 2 | 3 | To develop Cloudstate services, you need to prepare a Kubernetes cluster and install Cloudstate. We suggest that once your development environment is ready, you follow one of our example tutorials. That will help you verify that your environment is configured correctly and will help you learn Cloudstate basics. 4 | -------------------------------------------------------------------------------- /docs/src/modules/develop/pages/install.adoc: -------------------------------------------------------------------------------- 1 | = Installing Cloudstate 2 | 3 | include::develop:partial$install.adoc[] 4 | 5 | -------------------------------------------------------------------------------- /docs/src/modules/develop/pages/prerequisites.adoc: -------------------------------------------------------------------------------- 1 | = Prerequisites 2 | 3 | include::develop:partial$prerequisites.adoc[] 4 | 5 | -------------------------------------------------------------------------------- /docs/src/modules/develop/pages/tutorial.adoc: -------------------------------------------------------------------------------- 1 | = The shopping cart tutorial 2 | 3 | include::develop:partial$tutorial.adoc[] 4 | -------------------------------------------------------------------------------- /docs/src/shared/antora.yml: -------------------------------------------------------------------------------- 1 | name: "" 2 | version: master 3 | -------------------------------------------------------------------------------- /docs/src/shared/modules/ROOT/images/abstract_over_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/docs/src/shared/modules/ROOT/images/abstract_over_state.png -------------------------------------------------------------------------------- /docs/src/shared/modules/ROOT/images/data_model_crdts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/docs/src/shared/modules/ROOT/images/data_model_crdts.png -------------------------------------------------------------------------------- /docs/src/shared/modules/ROOT/images/data_model_event_sourcing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/docs/src/shared/modules/ROOT/images/data_model_event_sourcing.png -------------------------------------------------------------------------------- /docs/src/shared/modules/ROOT/images/faas-crud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/docs/src/shared/modules/ROOT/images/faas-crud.png -------------------------------------------------------------------------------- /docs/src/shared/modules/ROOT/images/powered_by_akka_sidecars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/docs/src/shared/modules/ROOT/images/powered_by_akka_sidecars.png -------------------------------------------------------------------------------- /docs/src/shared/modules/ROOT/images/serving_stateful_functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/docs/src/shared/modules/ROOT/images/serving_stateful_functions.png -------------------------------------------------------------------------------- /docs/src/shared/modules/ROOT/partials/examples.adoc: -------------------------------------------------------------------------------- 1 | Lightbend maintains two example applications, a trivial chat service and a shopping cart, in each of the supported languages. 2 | 3 | ifdef::todo[TODO: add links to the sample app repos.] 4 | -------------------------------------------------------------------------------- /docs/src/shared/modules/concepts/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Important concepts] 2 | ** xref:glossary.adoc[Glossary] 3 | ** xref:grpc.adoc[gRPC] 4 | ** xref:eventsourced.adoc[Event sourcing] 5 | ** xref:crdts.adoc[Conflict-free replicated data types] 6 | ** xref:effects.adoc[Forwarding and effects] 7 | -------------------------------------------------------------------------------- /docs/src/shared/modules/develop/partials/install.adoc: -------------------------------------------------------------------------------- 1 | This page will contain the procedures for installing Cloudstate. 2 | -------------------------------------------------------------------------------- /docs/src/shared/modules/develop/partials/prerequisites.adoc: -------------------------------------------------------------------------------- 1 | This page will contain the procedures for all Cloudstate prerequisites, including anything special they need to do/have in their Kubernetes cluster and installing Istio. It should also explain that there may be additional prereqs depending on the language the reader wants to write their services in and link to those pages. 2 | -------------------------------------------------------------------------------- /docs/src/shared/modules/develop/partials/tutorial.adoc: -------------------------------------------------------------------------------- 1 | Include content from the tutorial repo that describes the tutorial. List the languages available and link to the appropriate place. 2 | -------------------------------------------------------------------------------- /graal-tools/src/main/scala/io/cloudstate/graaltools/Existence.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.graaltools 18 | 19 | import java.util.function.Predicate 20 | 21 | final class Existence extends Predicate[String] { 22 | def test(s: String) = 23 | try { 24 | Class.forName(s, false, Thread.currentThread.getContextClassLoader) 25 | true 26 | } catch { case _: ClassNotFoundException | _: NoClassDefFoundError => false } 27 | } 28 | -------------------------------------------------------------------------------- /images/abstract_over_state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/images/abstract_over_state.png -------------------------------------------------------------------------------- /images/data_model_crdts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/images/data_model_crdts.png -------------------------------------------------------------------------------- /images/data_model_event_sourcing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/images/data_model_event_sourcing.png -------------------------------------------------------------------------------- /images/faas_with_crud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/images/faas_with_crud.png -------------------------------------------------------------------------------- /images/powered_by_akka_sidecars.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/images/powered_by_akka_sidecars.png -------------------------------------------------------------------------------- /images/serving_stateful_functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/images/serving_stateful_functions.png -------------------------------------------------------------------------------- /java-support/docs/.gitignore: -------------------------------------------------------------------------------- 1 | /.cache/ 2 | /.deploy/ 3 | /build/ 4 | -------------------------------------------------------------------------------- /java-support/docs/config/validate-links.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignorePatterns": [ 3 | { "pattern": "^http://maven\\.apache\\.org/POM" } 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /java-support/docs/src/antora.yml: -------------------------------------------------------------------------------- 1 | name: "" 2 | version: master 3 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/examples/docs/user/gettingstarted/ShoppingCartMain.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package docs.user.gettingstarted; 18 | 19 | // tag::shopping-cart-main[] 20 | import com.example.Shoppingcart; 21 | import io.cloudstate.javasupport.CloudState; 22 | 23 | public class ShoppingCartMain { 24 | 25 | public static void main(String... args) { 26 | new CloudState() 27 | .registerEventSourcedEntity( 28 | ShoppingCartEntity.class, 29 | Shoppingcart.getDescriptor().findServiceByName("ShoppingCart")) 30 | .start(); 31 | } 32 | } 33 | // end::shopping-cart-main[] 34 | 35 | class ShoppingCartEntity {} 36 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/examples/proto/domain.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package example.shoppingcart.domain; 4 | 5 | option java_package = "com.example"; 6 | 7 | message LineItem { 8 | string productId = 1; 9 | string name = 2; 10 | int32 quantity = 3; 11 | } 12 | 13 | message ItemAdded { 14 | LineItem item = 1; 15 | } 16 | 17 | message ItemRemoved { 18 | string productId = 1; 19 | } 20 | 21 | message CheckedOut {} 22 | 23 | message Cart { 24 | repeated LineItem items = 1; 25 | bool checkedout = 2; 26 | } 27 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/examples/proto/hotitems.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "google/protobuf/empty.proto"; 4 | import "cloudstate/entity_key.proto"; 5 | 6 | package example.shoppingcart; 7 | 8 | option java_package = "com.example"; 9 | 10 | service HotItemsService { 11 | rpc ItemAddedToCart(Item) returns (google.protobuf.Empty); 12 | } 13 | 14 | message Item { 15 | string product_id = 1; 16 | string name = 2; 17 | int32 quantity = 3; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/examples/proto/shoppingcart.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "google/protobuf/empty.proto"; 4 | import "cloudstate/entity_key.proto"; 5 | 6 | package example.shoppingcart; 7 | 8 | option java_package = "com.example"; 9 | 10 | service ShoppingCartService { 11 | rpc AddItem(AddLineItem) returns (google.protobuf.Empty); 12 | rpc RemoveItem(RemoveLineItem) returns (google.protobuf.Empty); 13 | rpc GetCart(GetShoppingCart) returns (Cart); 14 | rpc WatchCart(GetShoppingCart) returns (stream Cart); 15 | } 16 | 17 | message AddLineItem { 18 | string user_id = 1 [(.cloudstate.entity_key) = true]; 19 | string product_id = 2; 20 | string name = 3; 21 | int32 quantity = 4; 22 | } 23 | 24 | message RemoveLineItem { 25 | string user_id = 1 [(.cloudstate.entity_key) = true]; 26 | string product_id = 2; 27 | } 28 | 29 | message GetShoppingCart { 30 | string user_id = 1 [(.cloudstate.entity_key) = true]; 31 | } 32 | 33 | message LineItem { 34 | string product_id = 1; 35 | string name = 2; 36 | int32 quantity = 3; 37 | } 38 | 39 | message Cart { 40 | repeated LineItem items = 1; 41 | } 42 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Implementing in Java] 2 | ** xref:getting-started.adoc[Getting started] 3 | ** xref:eventsourced.adoc[Event sourcing] 4 | ** xref:crdt.adoc[Conflict-free Replicated Data Types] 5 | ** xref:effects.adoc[Forwarding and effects] 6 | ** xref:serialization.adoc[Serialization] 7 | ** xref:api.adoc[Java API docs] 8 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/pages/api.adoc: -------------------------------------------------------------------------------- 1 | = Java API docs 2 | 3 | The Java API docs can be found link:{attachmentsdir}/api/index.html[here]. 4 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Implementing in Java 2 | 3 | Cloudstate offers an idiomatic, annotation based Java support library for writing stateful services. Before you attempt to write your first service in Java, we recommend that you understand Cloudstate concepts and terminology. We also suggest that you work through one of the tutorials first. 4 | 5 | * xref:getting-started.adoc[Getting started] 6 | * xref:eventsourced.adoc[Event sourcing] 7 | * xref:crdt.adoc[Conflict-free Replicated Data Types] 8 | * xref:effects.adoc[Forwarding and effects] 9 | * xref:serialization.adoc[Serialization] 10 | * link:{attachmentsdir}/api/index.html[Java API docs] 11 | -------------------------------------------------------------------------------- /java-support/docs/src/modules/java/partials/include.adoc: -------------------------------------------------------------------------------- 1 | :minimum-java-version: 8 2 | :recommended-java-version: 11 3 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/Context.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport; 18 | 19 | /** Root class of all contexts. */ 20 | public interface Context { 21 | /** Get the service call factory for this stateful service. */ 22 | ServiceCallFactory serviceCallFactory(); 23 | } 24 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/EntityContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport; 18 | 19 | /** 20 | * Root context for all contexts that pertain to entities, that is, things that are addressable via 21 | * an entity id. 22 | */ 23 | public interface EntityContext extends Context { 24 | 25 | /** 26 | * The id of the entity that this context is for. 27 | * 28 | * @return The entity id. 29 | */ 30 | String entityId(); 31 | } 32 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/EntityFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport; 18 | 19 | /** Entity factory for supporting DI environments. */ 20 | public interface EntityFactory { 21 | /** 22 | * Create an entity. 23 | * 24 | * @return the new entity 25 | */ 26 | Object create(EntityContext context); 27 | 28 | /** 29 | * Get the class of the entity. 30 | * 31 | * @return the entity class 32 | */ 33 | Class entityClass(); 34 | } 35 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/EntityOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport; 18 | 19 | /** Options used for configuring an entity. */ 20 | public interface EntityOptions { 21 | 22 | /** @return the passivation strategy for an entity */ 23 | PassivationStrategy passivationStrategy(); 24 | 25 | /** 26 | * Create an entity option with the given passivation strategy. 27 | * 28 | * @param strategy to be used 29 | * @return the entity option 30 | */ 31 | EntityOptions withPassivationStrategy(PassivationStrategy strategy); 32 | } 33 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/Jsonable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport; 18 | 19 | import io.cloudstate.javasupport.impl.CloudStateAnnotation; 20 | 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | /** Indicates that this class can be serialized to/from JSON. */ 27 | @CloudStateAnnotation 28 | @Retention(RetentionPolicy.RUNTIME) 29 | @Target(ElementType.TYPE) 30 | public @interface Jsonable {} 31 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/MetadataContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport; 18 | 19 | /** Context that provides access to metadata. */ 20 | public interface MetadataContext extends Context { 21 | /** Get the metadata associated with this context. */ 22 | Metadata metadata(); 23 | } 24 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/action/Action.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.action; 18 | 19 | import io.cloudstate.javasupport.impl.CloudStateAnnotation; 20 | 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | /** An action. */ 27 | @CloudStateAnnotation 28 | @Target(ElementType.TYPE) 29 | @Retention(RetentionPolicy.RUNTIME) 30 | public @interface Action {} 31 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/action/FailureReply.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.action; 18 | 19 | import java.util.Collection; 20 | 21 | /** A failure reply. */ 22 | public interface FailureReply extends ActionReply { 23 | 24 | /** 25 | * The description of the failure. 26 | * 27 | * @return The failure description. 28 | */ 29 | String description(); 30 | 31 | FailureReply withEffects(Collection effects); 32 | 33 | FailureReply withEffects(Effect... effects); 34 | } 35 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/action/ForwardReply.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.action; 18 | 19 | import io.cloudstate.javasupport.ServiceCall; 20 | 21 | import java.util.Collection; 22 | 23 | /** A forward reply. */ 24 | public interface ForwardReply extends ActionReply { 25 | 26 | /** 27 | * The service call that is being forwarded to. 28 | * 29 | * @return The service call. 30 | */ 31 | ServiceCall serviceCall(); 32 | 33 | ForwardReply withEffects(Collection effects); 34 | 35 | ForwardReply withEffects(Effect... effects); 36 | } 37 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/action/MessageReply.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.action; 18 | 19 | import io.cloudstate.javasupport.Metadata; 20 | 21 | import java.util.Collection; 22 | 23 | /** A message reply. */ 24 | public interface MessageReply extends ActionReply { 25 | 26 | /** 27 | * The payload of the message reply. 28 | * 29 | * @return The payload. 30 | */ 31 | T payload(); 32 | 33 | /** 34 | * The metadata associated with the message. 35 | * 36 | * @return The metadata. 37 | */ 38 | Metadata metadata(); 39 | 40 | MessageReply withEffects(Collection effects); 41 | 42 | MessageReply withEffects(Effect... effects); 43 | } 44 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/crdt/Crdt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.crdt; 18 | 19 | /** Root interface for all CRDTs. */ 20 | public interface Crdt {} 21 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/crdt/CrdtCreationContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.crdt; 18 | 19 | /** 20 | * Context for CRDT creation. 21 | * 22 | *

This is available for injection into the constructor of a CRDT. 23 | */ 24 | public interface CrdtCreationContext extends CrdtContext, CrdtFactory {} 25 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/crdt/Flag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.crdt; 18 | 19 | /** 20 | * A flag CRDT. 21 | * 22 | *

A flag is a boolean value that starts out as false, and once set to true 23 | * , stays true, it cannot be set back to false. 24 | */ 25 | public interface Flag extends Crdt { 26 | /** 27 | * Whether this flag is enabled. 28 | * 29 | * @return True if the flag is enabled. 30 | */ 31 | boolean isEnabled(); 32 | 33 | /** Enable this flag. */ 34 | void enable(); 35 | } 36 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/crdt/StreamCancelledContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.crdt; 18 | 19 | import io.cloudstate.javasupport.EffectContext; 20 | import io.cloudstate.javasupport.MetadataContext; 21 | 22 | import java.util.function.Consumer; 23 | 24 | /** 25 | * Context for a stream cancelled event. 26 | * 27 | *

This is sent to callbacks registered by {@link StreamedCommandContext#onCancel(Consumer)}. 28 | */ 29 | public interface StreamCancelledContext extends CrdtContext, EffectContext, MetadataContext { 30 | /** 31 | * The id of the command that the stream was for. 32 | * 33 | * @return The ID of the command. 34 | */ 35 | long commandId(); 36 | } 37 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/crdt/SubscriptionContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.crdt; 18 | 19 | import io.cloudstate.javasupport.ClientActionContext; 20 | import io.cloudstate.javasupport.EffectContext; 21 | 22 | import java.util.function.Function; 23 | 24 | /** 25 | * The context for a subscription, passed with every invocation of a {@link 26 | * StreamedCommandContext#onChange(Function)} callback. 27 | */ 28 | public interface SubscriptionContext extends CrdtContext, EffectContext, ClientActionContext { 29 | /** End this stream. */ 30 | void endStream(); 31 | } 32 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/crdt/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Conflict-free Replicated Data Type support. 3 | * 4 | *

CRDT entities can be annotated with the {@link 5 | * io.cloudstate.javasupport.crdt.CrdtEntity @CrdtEntity} annotation, and supply command handlers 6 | * using the {@link io.cloudstate.javasupport.crdt.CommandHandler @CommandHandler} annotation. 7 | * 8 | *

The data stored by a CRDT entity can be stored in a subtype of {@link 9 | * io.cloudstate.javasupport.crdt.Crdt}. These can be created using a {@link 10 | * io.cloudstate.javasupport.crdt.CrdtFactory}, which is a super-interface of both the {@link 11 | * io.cloudstate.javasupport.crdt.CrdtCreationContext}, available for injection constructors, and of 12 | * the {@link io.cloudstate.javasupport.crdt.CommandContext}, available for injection in 13 | * {@code @CommandHandler} annotated methods. 14 | */ 15 | package io.cloudstate.javasupport.crdt; 16 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/entity/EntityContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.entity; 18 | 19 | /** Root context for all value based entity contexts. */ 20 | public interface EntityContext extends io.cloudstate.javasupport.EntityContext {} 21 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/entity/EntityCreationContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.entity; 18 | 19 | /** 20 | * Creation context for {@link Entity} annotated entities. 21 | * 22 | *

This may be accepted as an argument to the constructor of a value based entity. 23 | */ 24 | public interface EntityCreationContext extends EntityContext {} 25 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/entity/EntityFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.entity; 18 | 19 | /** 20 | * Low level interface for handling commands on a value based entity. 21 | * 22 | *

Generally, this should not be needed, instead, a class annotated with the {@link 23 | * CommandHandler} and similar annotations should be used. 24 | */ 25 | public interface EntityFactory { 26 | /** 27 | * Create an entity handler for the given context. 28 | * 29 | * @param context The context. 30 | * @return The handler for the given context. 31 | */ 32 | EntityHandler create(EntityContext context); 33 | } 34 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/entity/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Value based entity support. 3 | * 4 | *

Value based entities can be annotated with the {@link 5 | * io.cloudstate.javasupport.entity.Entity @Entity} annotation, and supply command handlers using 6 | * the {@link io.cloudstate.javasupport.entity.CommandHandler @CommandHandler} annotation. 7 | */ 8 | package io.cloudstate.javasupport.entity; 9 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/eventsourced/EventContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.eventsourced; 18 | 19 | /** Context for an event. */ 20 | public interface EventContext extends EventSourcedContext { 21 | /** 22 | * The sequence number of the current event being processed. 23 | * 24 | * @return The sequence number. 25 | */ 26 | long sequenceNumber(); 27 | } 28 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/eventsourced/EventSourcedContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.eventsourced; 18 | 19 | import io.cloudstate.javasupport.EntityContext; 20 | 21 | /** Root context for all event sourcing contexts. */ 22 | public interface EventSourcedContext extends EntityContext {} 23 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/eventsourced/EventSourcedEntityCreationContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.eventsourced; 18 | 19 | /** 20 | * Creation context for {@link EventSourcedEntity} annotated entities. 21 | * 22 | *

This may be accepted as an argument to the constructor of an event sourced entity. 23 | */ 24 | public interface EventSourcedEntityCreationContext extends EventSourcedContext {} 25 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/eventsourced/SnapshotContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.eventsourced; 18 | 19 | /** A snapshot context. */ 20 | public interface SnapshotContext extends EventSourcedContext { 21 | /** 22 | * The sequence number of the last event that this snapshot includes. 23 | * 24 | * @return The sequence number. 25 | */ 26 | long sequenceNumber(); 27 | } 28 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/eventsourced/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Event Sourcing support. 3 | * 4 | *

Event sourced entities can be annotated with the {@link 5 | * io.cloudstate.javasupport.eventsourced.EventSourcedEntity @EventSourcedEntity} annotation, and 6 | * supply command handlers using the {@link 7 | * io.cloudstate.javasupport.eventsourced.CommandHandler @CommandHandler} annotation. 8 | * 9 | *

In addition, {@link io.cloudstate.javasupport.eventsourced.EventHandler @EventHandler} 10 | * annotated methods should be defined to handle events, and {@link 11 | * io.cloudstate.javasupport.eventsourced.Snapshot @Snapshot} and {@link 12 | * io.cloudstate.javasupport.eventsourced.SnapshotHandler @SnapshotHandler} annotated methods should 13 | * be defined to produce and handle snapshots respectively. 14 | */ 15 | package io.cloudstate.javasupport.eventsourced; 16 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/impl/CloudStateAnnotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.impl; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | /** Mark annotation for all CloudState annotations */ 25 | @Target(ElementType.ANNOTATION_TYPE) 26 | @Retention(RetentionPolicy.RUNTIME) 27 | public @interface CloudStateAnnotation {} 28 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/impl/package-info.java: -------------------------------------------------------------------------------- 1 | /** Internal implementation classes for CloudState Java Support. */ 2 | package io.cloudstate.javasupport.impl; 3 | -------------------------------------------------------------------------------- /java-support/src/main/java/io/cloudstate/javasupport/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Root package for the CloudState Java Support library. 3 | * 4 | *

The main entry point to creating a CloudState Java server is the {@link 5 | * io.cloudstate.javasupport.CloudState} class. 6 | * 7 | *

For information about specific entity types, see: 8 | * 9 | *

10 | *
11 | * io.cloudstate.javasupport.eventsourced 12 | *
Event Sourcing support 13 | *
14 | * io.cloudstate.javasupport.crdt 15 | *
Conflict-free Replicated Data Type support 16 | *
17 | */ 18 | package io.cloudstate.javasupport; 19 | -------------------------------------------------------------------------------- /java-support/src/main/java/overview.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | These are the API docs for the CloudState Java Support project. 8 | 9 | -------------------------------------------------------------------------------- /java-support/src/main/resources/reference.conf: -------------------------------------------------------------------------------- 1 | cloudstate { 2 | user-function-interface = "127.0.0.1" 3 | user-function-interface = ${?HOST} 4 | 5 | user-function-port = 8080 6 | user-function-port = ${?PORT} 7 | 8 | // default passivation timeout for entities 9 | passivation-timeout = 30s 10 | 11 | eventsourced { 12 | snapshot-every = 100 13 | } 14 | 15 | system { 16 | akka { 17 | actor { 18 | provider = local 19 | } 20 | 21 | coordinated-shutdown.exit-jvm = on 22 | 23 | http.server { 24 | preview.enable-http2 = on 25 | 26 | // Disable - we receive connections from localhost, so they'll never be dropped 27 | idle-timeout = infinite 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java-support/src/main/scala/io/cloudstate/javasupport/impl/PassivationStrategies.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.impl 18 | 19 | import java.time.Duration 20 | 21 | import io.cloudstate.javasupport.PassivationStrategy 22 | 23 | private[impl] case class Timeout private (duration: Option[Duration]) extends PassivationStrategy { 24 | 25 | def this() { 26 | this(None) // use the timeout from the default or customized settings 27 | } 28 | 29 | def this(duration: Duration) { 30 | this(Some(duration)) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /java-support/src/main/scala/io/cloudstate/javasupport/impl/crdt/CrdtEntityOptionsImpl.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.impl.crdt 18 | 19 | import io.cloudstate.javasupport.crdt.CrdtEntityOptions 20 | import io.cloudstate.javasupport.PassivationStrategy 21 | 22 | private[impl] case class CrdtEntityOptionsImpl(override val passivationStrategy: PassivationStrategy) 23 | extends CrdtEntityOptions { 24 | 25 | override def withPassivationStrategy(strategy: PassivationStrategy): CrdtEntityOptions = 26 | copy(passivationStrategy = strategy) 27 | } 28 | -------------------------------------------------------------------------------- /java-support/src/main/scala/io/cloudstate/javasupport/impl/crdt/InternalCrdt.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.impl.crdt 18 | 19 | import io.cloudstate.javasupport.crdt.Crdt 20 | import io.cloudstate.protocol.crdt.CrdtDelta 21 | 22 | private[crdt] trait InternalCrdt extends Crdt { 23 | def name: String 24 | def hasDelta: Boolean 25 | def delta: CrdtDelta.Delta 26 | def resetDelta(): Unit 27 | def applyDelta: PartialFunction[CrdtDelta.Delta, Unit] 28 | } 29 | -------------------------------------------------------------------------------- /java-support/src/main/scala/io/cloudstate/javasupport/impl/entity/EntityOptionsImpl.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.impl.entity 18 | 19 | import io.cloudstate.javasupport.entity.EntityOptions 20 | import io.cloudstate.javasupport.PassivationStrategy 21 | 22 | private[impl] case class ValueEntityOptionsImpl(override val passivationStrategy: PassivationStrategy) 23 | extends EntityOptions { 24 | 25 | override def withPassivationStrategy(strategy: PassivationStrategy): EntityOptions = 26 | copy(passivationStrategy = strategy) 27 | } 28 | -------------------------------------------------------------------------------- /java-support/src/main/scala/io/cloudstate/javasupport/impl/eventsourced/EventSourcedEntityOptionsImpl.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.impl.eventsourced 18 | 19 | import io.cloudstate.javasupport.eventsourced.EventSourcedEntityOptions 20 | import io.cloudstate.javasupport.PassivationStrategy 21 | 22 | private[impl] case class EventSourcedEntityOptionsImpl(override val passivationStrategy: PassivationStrategy) 23 | extends EventSourcedEntityOptions { 24 | 25 | override def withPassivationStrategy(strategy: PassivationStrategy): EventSourcedEntityOptions = 26 | copy(passivationStrategy = strategy) 27 | } 28 | -------------------------------------------------------------------------------- /java-support/src/test/proto/cloudstate/javasupport/actionspec.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package cloudstate.javasupport; 18 | 19 | message In { 20 | string field = 1; 21 | } 22 | 23 | message Out { 24 | string field = 1; 25 | } 26 | 27 | service ActionSpec { 28 | rpc Unary(In) returns (Out); 29 | rpc StreamedIn(stream In) returns (Out); 30 | rpc StreamedOut(In) returns (stream Out); 31 | rpc Streamed(stream In) returns (stream Out); 32 | } 33 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/action/ActionTwoBehavior.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.action; 18 | 19 | import io.cloudstate.javasupport.action.*; 20 | import io.cloudstate.tck.model.Action.*; 21 | 22 | @Action 23 | public class ActionTwoBehavior { 24 | public ActionTwoBehavior() {} 25 | 26 | @CallHandler 27 | public Response call(OtherRequest request) { 28 | return Response.getDefaultInstance(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/crdt/CrdtConfiguredEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.crdt; 18 | 19 | import io.cloudstate.javasupport.crdt.*; 20 | import io.cloudstate.tck.model.Crdt.*; 21 | 22 | @CrdtEntity 23 | public class CrdtConfiguredEntity { 24 | 25 | @CommandHandler 26 | public Response call(Request request) { 27 | return Response.getDefaultInstance(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/crdt/CrdtTwoEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.crdt; 18 | 19 | import io.cloudstate.javasupport.crdt.*; 20 | import io.cloudstate.tck.model.Crdt.*; 21 | 22 | @CrdtEntity 23 | public class CrdtTwoEntity { 24 | // create a CRDT to be able to call delete 25 | public CrdtTwoEntity(GCounter counter) {} 26 | 27 | @CommandHandler 28 | public Response call(Request request, CommandContext context) { 29 | for (RequestAction action : request.getActionsList()) { 30 | if (action.hasDelete()) context.delete(); 31 | } 32 | return Response.getDefaultInstance(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/eventlogeventing/JsonMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.eventlogeventing; 18 | 19 | import io.cloudstate.javasupport.Jsonable; 20 | 21 | @Jsonable 22 | public class JsonMessage { 23 | public JsonMessage(String message) { 24 | this.message = message; 25 | } 26 | 27 | public JsonMessage() {} 28 | 29 | public String message; 30 | } 31 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/eventsourced/EventSourcedConfiguredEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.eventsourced; 18 | 19 | import io.cloudstate.javasupport.eventsourced.*; 20 | import io.cloudstate.tck.model.Eventsourced.*; 21 | 22 | @EventSourcedEntity(persistenceId = "event-sourced-configured") 23 | public class EventSourcedConfiguredEntity { 24 | 25 | @CommandHandler 26 | public Response call(Request request) { 27 | return Response.getDefaultInstance(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/eventsourced/EventSourcedTwoEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.eventsourced; 18 | 19 | import io.cloudstate.javasupport.eventsourced.*; 20 | import io.cloudstate.tck.model.Eventsourced.*; 21 | 22 | @EventSourcedEntity 23 | public class EventSourcedTwoEntity { 24 | 25 | @CommandHandler 26 | public Response call(Request request) { 27 | return Response.getDefaultInstance(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/valuebased/ValueEntityConfiguredEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.valuebased; 18 | 19 | import io.cloudstate.javasupport.entity.CommandHandler; 20 | import io.cloudstate.javasupport.entity.Entity; 21 | import io.cloudstate.tck.model.valueentity.Valueentity.Request; 22 | import io.cloudstate.tck.model.valueentity.Valueentity.Response; 23 | 24 | @Entity(persistenceId = "value-entity-configured") 25 | public class ValueEntityConfiguredEntity { 26 | 27 | @CommandHandler 28 | public Response call(Request request) { 29 | return Response.getDefaultInstance(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java-support/tck/src/main/java/io/cloudstate/javasupport/tck/model/valuebased/ValueEntityTwoEntity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.javasupport.tck.model.valuebased; 18 | 19 | import io.cloudstate.javasupport.entity.Entity; 20 | import io.cloudstate.javasupport.entity.CommandHandler; 21 | import io.cloudstate.tck.model.valueentity.Valueentity.Request; 22 | import io.cloudstate.tck.model.valueentity.Valueentity.Response; 23 | 24 | @Entity(persistenceId = "value-entity-tck-model-two") 25 | public class ValueEntityTwoEntity { 26 | 27 | @CommandHandler 28 | public Response call(Request request) { 29 | return Response.getDefaultInstance(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /node-support/.gitignore: -------------------------------------------------------------------------------- 1 | proto 2 | protoc 3 | apidocs 4 | -------------------------------------------------------------------------------- /node-support/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /node-support/.nvmrc: -------------------------------------------------------------------------------- 1 | v12 2 | -------------------------------------------------------------------------------- /node-support/RELEASING.md: -------------------------------------------------------------------------------- 1 | # Releasing Cloudstate node-support 2 | 3 | 1. Bump the node-support version with `npm version [major|minor|patch]` and commit 4 | 2. Create a `node-support-x.y.z` tag and [new release](https://github.com/cloudstateio/cloudstate/releases/new) for the new version 5 | 3. Travis will automatically publish the [cloudstate package](https://www.npmjs.com/package/cloudstate) to npm based on the tag 6 | -------------------------------------------------------------------------------- /node-support/bin/prepare.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Prepare script for the cloudstate package 4 | 5 | # Delete and recreate the proto directory 6 | rm -rf ./proto 7 | mkdir -p ./proto 8 | cp -r ../protocols/frontend/* ../protocols/protocol/* ./proto/ 9 | 10 | # Generate the protobuf bundle and typescript definitions 11 | pbjs -t static-module -w commonjs -o ./proto/protobuf-bundle.js -p ./proto -p ./protoc/include ./proto/cloudstate/*.proto 12 | pbjs -t static-module -p ./proto -p ./protoc/include proto/cloudstate/*.proto | pbts -o ./proto/protobuf-bundle.d.ts - -------------------------------------------------------------------------------- /node-support/docs/.gitignore: -------------------------------------------------------------------------------- 1 | /.cache/ 2 | /.deploy/ 3 | /build/ 4 | -------------------------------------------------------------------------------- /node-support/docs/src/antora.yml: -------------------------------------------------------------------------------- 1 | name: "" 2 | version: master 3 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.desc 3 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/.nvmrc: -------------------------------------------------------------------------------- 1 | v12 2 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/domain.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package example.shoppingcart.domain; 4 | 5 | message LineItem { 6 | string productId = 1; 7 | string name = 2; 8 | int32 quantity = 3; 9 | } 10 | 11 | message ItemAdded { 12 | LineItem item = 1; 13 | } 14 | 15 | message ItemRemoved { 16 | string productId = 1; 17 | } 18 | 19 | message CheckedOut {} 20 | 21 | message Cart { 22 | repeated LineItem items = 1; 23 | bool checkedout = 2; 24 | } 25 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudstate-documentation-samples", 3 | "version": "0.0.1", 4 | "description": "Code samples for the CloudState documentation", 5 | "homepage": "https://cloudstate.io", 6 | "license": "Apache-2.0", 7 | "engineStrict": true, 8 | "engines": { 9 | "node": "~12" 10 | }, 11 | "//": "https://npm.community/t/npm-install-does-not-install-transitive-dependencies-of-local-dependency/2264", 12 | "dependencies": { 13 | "@grpc/proto-loader": "^0.1.0", 14 | "google-protobuf": "^3.0.0", 15 | "grpc": "^1.20.2", 16 | "cloudstate": "file:../../../../.." 17 | }, 18 | "devDependencies": { 19 | "chai": "4.2.0", 20 | "mocha": "^6.1.4" 21 | }, 22 | "scripts": { 23 | "test": "mocha --recursive", 24 | "pretest": "compile-descriptor shoppingcart.proto && compile-descriptor shoppingcart.proto --descriptor_set_out=my-descriptor.desc" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/shoppingcart.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "google/protobuf/empty.proto"; 4 | import "cloudstate/entity_key.proto"; 5 | 6 | package example.shoppingcart; 7 | 8 | service ShoppingCartService { 9 | rpc AddItem(AddLineItem) returns (google.protobuf.Empty); 10 | rpc RemoveItem(RemoveLineItem) returns (google.protobuf.Empty); 11 | rpc GetCart(GetShoppingCart) returns (Cart); 12 | } 13 | 14 | message AddLineItem { 15 | string user_id = 1 [(.cloudstate.entity_key) = true]; 16 | string product_id = 2; 17 | string name = 3; 18 | int32 quantity = 4; 19 | } 20 | 21 | message RemoveLineItem { 22 | string user_id = 1 [(.cloudstate.entity_key) = true]; 23 | string product_id = 2; 24 | } 25 | 26 | message GetShoppingCart { 27 | string user_id = 1 [(.cloudstate.entity_key) = true]; 28 | } 29 | 30 | message LineItem { 31 | string product_id = 1; 32 | string name = 2; 33 | int32 quantity = 3; 34 | } 35 | 36 | message Cart { 37 | repeated LineItem items = 1; 38 | } 39 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/test/gettingstarted/index.js: -------------------------------------------------------------------------------- 1 | 2 | const should = require('chai').should(); 3 | 4 | describe("The CloudState class", () => { 5 | 6 | it("should allow creating and starting a server", () => { 7 | 8 | // tag::start[] 9 | const cloudstate = require("cloudstate"); 10 | const shoppingcart = require("./shoppingcart"); 11 | 12 | const server = new cloudstate.CloudState(); 13 | server.addEntity(shoppingcart); 14 | server.start(); 15 | // end::start[] 16 | 17 | server.shutdown(); 18 | }); 19 | 20 | it("should allow using a custom descriptor name", () => { 21 | const cloudstate = require("cloudstate"); 22 | 23 | // tag::custom-desc[] 24 | const server = new cloudstate.CloudState({ 25 | descriptorSetPath: "my-descriptor.desc" 26 | }); 27 | // end::custom-desc[] 28 | 29 | }) 30 | }); 31 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/examples/test/gettingstarted/shoppingcart.js: -------------------------------------------------------------------------------- 1 | const cloudstate = require("cloudstate"); 2 | const entity = new cloudstate.EventSourced("shoppingcart.proto", "example.ShoppingCartService"); 3 | entity.setInitial(() => {}); 4 | entity.setBehavior(() => { 5 | return { 6 | commandHandlers: {}, 7 | eventHandlers: {} 8 | }; 9 | }); 10 | module.exports = entity; 11 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Implementing in JavaScript] 2 | ** xref:getting-started.adoc[Getting started] 3 | ** xref:eventsourced.adoc[Event sourcing] 4 | ** xref:crdt.adoc[Conflict-free Replicated Data Types] 5 | ** xref:effects.adoc[Forwarding and effects] 6 | ** xref:serialization.adoc[Serialization] 7 | ** xref:api.adoc[JavaScript API docs] 8 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/pages/api.adoc: -------------------------------------------------------------------------------- 1 | = JavaScript API docs 2 | 3 | The JavaScript API docs can be found link:{attachmentsdir}/api/index.html[here]. 4 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/pages/crdt.adoc: -------------------------------------------------------------------------------- 1 | = Conflict-free Replicated Data Types 2 | 3 | * Explain how to use the CRDT API 4 | * Explain default values 5 | * Explain onStateSet 6 | * Explain how to handle streamed calls 7 | * Explain the APIs for each different CRDT 8 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/pages/effects.adoc: -------------------------------------------------------------------------------- 1 | = Forwarding and effects 2 | 3 | * Explain how to forward replies to another service. 4 | * Explain how to emit effects. 5 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Implementing in JavaScript 2 | 3 | Cloudstate offers a straightforward JavaScript API for implementing Cloudstate services. 4 | 5 | * xref:getting-started.adoc[Getting started] 6 | * xref:eventsourced.adoc[Event sourcing] 7 | * xref:crdt.adoc[Conflict-free Replicated Data Types] 8 | * xref:effects.adoc[Forwarding and effects] 9 | * xref:serialization.adoc[Serialization] 10 | * link:{attachmentsdir}/api/index.html[JavaScript API docs] 11 | -------------------------------------------------------------------------------- /node-support/docs/src/modules/javascript/pages/serialization.adoc: -------------------------------------------------------------------------------- 1 | = Serialization 2 | 3 | * Explain what serialization is provided, what types can be serialized etc. 4 | * Explain how to use protobufs for serialization. 5 | * Explain how to use primitive values for serialization. 6 | * Explain how to use JSON for serialization. 7 | -------------------------------------------------------------------------------- /node-support/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * The CloudState module. 19 | * 20 | * @module cloudstate 21 | */ 22 | 23 | module.exports.CloudState = require("./src/cloudstate"); 24 | module.exports.EventSourced = require("./src/eventsourced"); 25 | module.exports.crdt = require("./src/crdt"); 26 | module.exports.Action = require("./src/action"); 27 | module.exports.Metadata = require("./src/metadata"); 28 | -------------------------------------------------------------------------------- /node-support/jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true 4 | }, 5 | "source": { 6 | "include": [ 7 | "src", 8 | "index.js", 9 | "README.md" 10 | ], 11 | "exclude": [], 12 | "includePattern": ".+\\.js(doc)?$" 13 | }, 14 | "plugins": ["plugins/markdown"], 15 | "templates": { 16 | "cleverLinks": true, 17 | "monospaceLinks": false, 18 | "theme": "cosmo", 19 | "includeDate": false, 20 | "systemName": "CloudState" 21 | }, 22 | "opts": { 23 | "destination": "./apidocs/", 24 | "encoding": "utf8", 25 | "recurse": true, 26 | "template": "./node_modules/ink-docstrap/template" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /node-support/src/context-failure.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | module.exports = class ContextFailure extends Error { 18 | constructor(msg) { 19 | super(msg); 20 | if (Error.captureStackTrace) { 21 | Error.captureStackTrace(this, ContextFailure); 22 | } 23 | this.name = "ContextFailure"; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /node-support/tck/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /proto/ 3 | /user-function.desc 4 | -------------------------------------------------------------------------------- /node-support/tck/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /node-support/tck/.nvmrc: -------------------------------------------------------------------------------- 1 | v12 2 | -------------------------------------------------------------------------------- /node-support/tck/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const CloudState = require("cloudstate").CloudState; 18 | const server = new CloudState(); 19 | const eventSourced = require("./eventsourced.js"); 20 | server.addEntity(eventSourced.tckModel); 21 | server.addEntity(eventSourced.two); 22 | server.start(); 23 | -------------------------------------------------------------------------------- /node-support/tck/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-support-tck", 3 | "version": "0.0.3", 4 | "description": "Cloudstate TCK implementation for Node support", 5 | "engineStrict": true, 6 | "engines": { 7 | "node": "~12" 8 | }, 9 | "dependencies": { 10 | "@grpc/proto-loader": "^0.1.0", 11 | "google-protobuf": "^3.11.4", 12 | "grpc": "^1.24.2", 13 | "cloudstate": "file:.." 14 | }, 15 | "scripts": { 16 | "prepare": "rm -rf proto && mkdir proto && cp ../../protocols/tck/cloudstate/tck/model/*.proto proto", 17 | "build": "npm run prepare && compile-descriptor ./proto/action.proto ./proto/crdt.proto ./proto/eventlogeventing.proto ./proto/eventsourced.proto ./proto/valueentity.proto", 18 | "postinstall": "npm run build", 19 | "start": "node index.js" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /node-support/test/example.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package com.example; 4 | 5 | message Example { 6 | string field1 = 1; 7 | string field2 = 2; 8 | } 9 | 10 | message PrimitiveLike { 11 | string field1 = 1; 12 | string field2 = 2; 13 | string field15 = 15; 14 | } 15 | 16 | message In { 17 | string field = 1; 18 | } 19 | 20 | message Out { 21 | string field = 1; 22 | } 23 | 24 | service ExampleService { 25 | rpc DoSomething(In) returns (Out); 26 | rpc StreamSomething(In) returns (stream Out); 27 | } -------------------------------------------------------------------------------- /operator/deploy/01-service-account.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: cloudstate-operator -------------------------------------------------------------------------------- /operator/deploy/03-role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRole 3 | metadata: 4 | name: cloudstate-operator-role 5 | rules: 6 | 7 | - apiGroups: [""] 8 | resources: ["namespaces"] 9 | verbs: ["get", "list", "watch"] 10 | 11 | - apiGroups: [""] 12 | resources: ["services", "pods"] 13 | verbs: ["get", "create", "delete", "patch", "update", "watch", "list"] 14 | 15 | - apiGroups: ["apps"] 16 | resources: ["deployments", "deployments/scale"] 17 | verbs: ["get", "create", "delete", "patch", "update", "watch", "list"] 18 | 19 | - apiGroups: ["rbac.authorization.k8s.io"] 20 | resources: ["rolebindings", "roles"] 21 | verbs: ["get", "create", "delete", "patch", "update"] 22 | 23 | - apiGroups: ["cloudstate.io"] 24 | resources: ["statefulstores", "statefulservices"] 25 | verbs: ["get", "list", "watch"] 26 | 27 | - apiGroups: ["cloudstate.io"] 28 | resources: ["statefulstores/status", "statefulservices/status"] 29 | verbs: ["update", "patch"] 30 | 31 | -------------------------------------------------------------------------------- /operator/deploy/04-role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: cloudstate-operator 5 | subjects: 6 | - kind: ServiceAccount 7 | name: cloudstate-operator 8 | namespace: cloudstate 9 | roleRef: 10 | kind: ClusterRole 11 | name: cloudstate-operator-role 12 | apiGroup: rbac.authorization.k8s.io 13 | 14 | -------------------------------------------------------------------------------- /operator/deploy/05-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: cloudstate-operator 5 | spec: 6 | replicas: 1 7 | strategy: 8 | type: Recreate 9 | selector: 10 | matchLabels: 11 | app: cloudstate-operator 12 | template: 13 | metadata: 14 | labels: 15 | app: cloudstate-operator 16 | annotations: 17 | sidecar.istio.io/inject: "false" 18 | spec: 19 | serviceAccountName: cloudstate-operator 20 | containers: 21 | - name: operator 22 | image: cloudstateio/cloudstate-operator:latest 23 | 24 | env: 25 | - name: JAVA_OPTS 26 | value: "-Xms128m -Xmx128m" 27 | - name: NAMESPACE 28 | valueFrom: 29 | fieldRef: 30 | fieldPath: "metadata.namespace" 31 | - name: CONFIG_MAP 32 | value: cloudstate-operator-config 33 | 34 | resources: 35 | limits: 36 | memory: 256Mi 37 | requests: 38 | cpu: 0.1 39 | memory: 256Mi 40 | -------------------------------------------------------------------------------- /operator/deploy/crds/stateful-service-crd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: statefulservices.cloudstate.io 5 | spec: 6 | group: cloudstate.io 7 | versions: 8 | - name: v1alpha1 9 | served: true 10 | storage: true 11 | scope: Namespaced 12 | names: 13 | plural: statefulservices 14 | singular: statefulservice 15 | kind: StatefulService 16 | subresources: 17 | status: {} 18 | -------------------------------------------------------------------------------- /operator/deploy/crds/stateful-store-crd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: statefulstores.cloudstate.io 5 | spec: 6 | group: cloudstate.io 7 | versions: 8 | - name: v1alpha1 9 | served: true 10 | storage: true 11 | scope: Namespaced 12 | names: 13 | plural: statefulstores 14 | singular: statefulstore 15 | kind: StatefulStore 16 | subresources: 17 | status: {} 18 | additionalPrinterColumns: 19 | - name: Type 20 | type: string 21 | description: The type of stateful store 22 | JSONPath: .spec.type 23 | - name: Age 24 | type: date 25 | JSONPath: .metadata.creationTimestamp 26 | 27 | -------------------------------------------------------------------------------- /operator/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | akka { 2 | coordinated-shutdown.exit-jvm = on 3 | 4 | loggers = ["akka.event.slf4j.Slf4jLogger"] 5 | loglevel = "INFO" 6 | logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" 7 | } -------------------------------------------------------------------------------- /operator/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /operator/src/main/resources/reference.conf: -------------------------------------------------------------------------------- 1 | cloudstate.operator { 2 | # Watch configuration 3 | watch { 4 | 5 | # This should be a list of namespaces to watch. Either should contain a single "*" to watch all namespaces 6 | # (this is configured in more detail below), or should be a list of namespaces. 7 | namespaces = ["*"] 8 | } 9 | 10 | # Proxy configuration 11 | proxy { 12 | image { 13 | cassandra = "cloudstateio/cloudstate-proxy-native-cassandra:latest" 14 | no-store = "cloudstateio/cloudstate-proxy-native-no-store:latest" 15 | in-memory = "cloudstateio/cloudstate-proxy-native-in-memory:latest" 16 | postgres = "cloudstateio/cloudstate-proxy-postgres:latest" 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /project/PublishPlugin.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | import bintray.{BintrayKeys, BintrayPlugin} 4 | 5 | /** 6 | * Publishing of JVM artifacts to Bintray. 7 | */ 8 | object PublishPlugin extends AutoPlugin { 9 | import BintrayKeys._ 10 | 11 | override def requires = BintrayPlugin && VersionPlugin 12 | override def trigger = allRequirements 13 | 14 | override def buildSettings = Seq( 15 | bintrayOrganization := Some("cloudstateio"), 16 | bintrayRelease / aggregate := false, // called once in root projects 17 | bintraySyncMavenCentral / aggregate := false 18 | ) 19 | 20 | override def projectSettings = Seq( 21 | bintrayRepository := { if (isSnapshot.value) "snapshots" else "releases" }, 22 | bintrayPackage := "cloudstate", 23 | bintrayReleaseOnPublish := false, // release and sync packages in one go 24 | pomIncludeRepository := (_ => false) 25 | ) 26 | } 27 | 28 | object NoPublish extends AutoPlugin { 29 | override def projectSettings = Seq( 30 | publish / skip := true 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /project/VersionPlugin.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | import sbtdynver.DynVerPlugin 4 | 5 | /** 6 | * Version settings — automatically added to all projects. 7 | */ 8 | object VersionPlugin extends AutoPlugin { 9 | import DynVerPlugin.autoImport._ 10 | 11 | override def requires = DynVerPlugin 12 | override def trigger = allRequirements 13 | 14 | // we need the DynVer build settings as project settings, so we can have per-project tag prefix and versions 15 | override def projectSettings = DynVerPlugin.buildSettings ++ Seq( 16 | version := dynverGitDescribeOutput.value.mkVersion(versionFmt, "latest"), 17 | dynver := version.value 18 | ) 19 | 20 | // make sure the version doesn't change based on time 21 | def versionFmt(out: sbtdynver.GitDescribeOutput): String = { 22 | val tagVersion = if (out.hasNoTags()) "0.0.0" else out.ref.dropPrefix 23 | val dirtySuffix = if (out.isDirty()) "-dev" else "" 24 | if (out.isCleanAfterTag) tagVersion 25 | else tagVersion + out.commitSuffix.mkString("-", "-", "") + dirtySuffix 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.13 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.4") 2 | 3 | addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") 4 | 5 | addSbtPlugin("com.lightbend.akka.grpc" % "sbt-akka-grpc" % "1.0.1") // When updating, also update GrpcJavaVersion in build.sbt to be in sync 6 | 7 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0") 8 | 9 | addSbtPlugin("com.lightbend.sbt" % "sbt-java-formatter" % "0.5.1") 10 | 11 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") 12 | 13 | addSbtPlugin("de.heikoseeberger" % "sbt-header" % "5.6.0") 14 | 15 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.10.0") 16 | 17 | addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6") 18 | 19 | addSbtPlugin("io.cloudstate" % "sbt-cloudstate-paradox" % "0.1.3") 20 | 21 | addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.10.0-RC1") 22 | -------------------------------------------------------------------------------- /protoc-installer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Argument 1 is Protobuf distribution version number, e.g. 3.7.1 4 | set -e 5 | 6 | DISTDIR="protoc_installation" 7 | DISTNAME="protoc-$1-linux-x86_64.zip" 8 | DISTURL="https://github.com/protocolbuffers/protobuf/releases/download/v$1/$DISTNAME" 9 | echo "Installing Protoc $1" 10 | wget --tries=2 --retry-connrefused $DISTURL 11 | unzip -q $DISTNAME -d $DISTDIR 12 | sudo cp $DISTDIR/bin/protoc /usr/local/bin/ 13 | sudo cp -r $DISTDIR/include/* /usr/local/include/ 14 | rm -rf $DISTDIR 15 | echo "Protoc $1 installed" -------------------------------------------------------------------------------- /protocols/example/valueentity/shoppingcart/persistence/domain.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // These are the messages that get persisted - the current state (Cart). 16 | syntax = "proto3"; 17 | 18 | package com.example.valueentity.shoppingcart.persistence; 19 | 20 | option go_package = "github.com/cloudstateio/go-support/example/valueentity/shoppingcart/persistence;persistence"; 21 | 22 | message LineItem { 23 | string productId = 1; 24 | string name = 2; 25 | int32 quantity = 3; 26 | } 27 | 28 | // The shopping cart state. 29 | message Cart { 30 | repeated LineItem items = 1; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /protocols/frontend/cloudstate/entity_key.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Extension for specifying which field in a message is to be considered an 16 | // entity key, for the purposes associating gRPC calls with entities and 17 | // sharding. 18 | 19 | syntax = "proto3"; 20 | 21 | import "google/protobuf/descriptor.proto"; 22 | 23 | package cloudstate; 24 | 25 | option java_package = "io.cloudstate"; 26 | option go_package = "github.com/cloudstateio/go-support/cloudstate;cloudstate"; 27 | 28 | extend google.protobuf.FieldOptions { 29 | bool entity_key = 1080; 30 | } 31 | -------------------------------------------------------------------------------- /protocols/frontend/cloudstate/legacy_entity_key.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Extension for specifying which field in a message is to be considered an 16 | // entity key, for the purposes associating gRPC calls with entities and 17 | // sharding. 18 | 19 | syntax = "proto3"; 20 | 21 | import "google/protobuf/descriptor.proto"; 22 | 23 | package cloudstate; 24 | 25 | option java_package = "io.cloudstate"; 26 | option go_package = "github.com/cloudstateio/go-support/cloudstate;cloudstate"; 27 | 28 | extend google.protobuf.FieldOptions { 29 | bool legacy_entity_key = 50002; 30 | } 31 | -------------------------------------------------------------------------------- /protocols/frontend/google/api/annotations.proto: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015, Google Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | syntax = "proto3"; 16 | 17 | package google.api; 18 | 19 | import "google/api/http.proto"; 20 | import "google/protobuf/descriptor.proto"; 21 | 22 | option csharp_namespace = "Google.Protobuf"; 23 | option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations"; 24 | option java_multiple_files = true; 25 | option java_outer_classname = "AnnotationsProto"; 26 | option java_package = "com.google.api"; 27 | option objc_class_prefix = "GAPI"; 28 | 29 | extend google.protobuf.MethodOptions { 30 | // See `HttpRule`. 31 | HttpRule http = 72295728; 32 | } 33 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/com.datastax.cassandra/cassandra-driver-core/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/com.datastax.cassandra/cassandra-driver-core/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "com.datastax.driver.core.Connection$Dispatcher" 4 | methods: [ 5 | {name: "exceptionCaught", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Throwable"]} 6 | {name: "userEventTriggered", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object"]} 7 | ] 8 | } 9 | { 10 | name: "com.datastax.driver.core.InboundTrafficMeter" 11 | methods: [{name: "channelRead", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object"]}] 12 | } 13 | { 14 | name: "com.datastax.driver.core.OutboundTrafficMeter" 15 | methods: [{name: "write", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object", "io.netty.channel.ChannelPromise"]}] 16 | }, 17 | ] 18 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/com.google.guava/guava/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/com.google.guava/guava/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "com.google.common.reflect.Types$TypeVariableImpl" 4 | allPublicMethods: true 5 | } 6 | { 7 | name: "com.google.common.util.concurrent.AbstractFuture" 8 | fields: [ 9 | {name: "listeners"} 10 | {name: "value"} 11 | {name: "waiters"} 12 | ] 13 | } 14 | { 15 | name: "com.google.common.util.concurrent.AbstractFuture$Waiter" 16 | fields: [ 17 | {name: "next"} 18 | {name: "thread"} 19 | ] 20 | } 21 | { 22 | name: "com.google.common.util.concurrent.Futures" 23 | methods: [{name: "transformAsync", parameterTypes: ["com.google.common.util.concurrent.ListenableFuture", "com.google.common.util.concurrent.AsyncFunction", "java.util.concurrent.Executor"]}] 24 | } 25 | ] 26 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/com.typesafe.akka/akka-persistence-cassandra/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/com.typesafe.akka/akka-persistence-cassandra/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.persistence.cassandra.ConfigSessionProvider" 4 | methods: [ 5 | {name: "", parameterTypes: ["akka.actor.ActorSystem", "com.typesafe.config.Config"]} 6 | ] 7 | } 8 | { 9 | name: "akka.persistence.cassandra.journal.CassandraJournal" 10 | allDeclaredFields: true 11 | allDeclaredConstructors: true 12 | } 13 | { 14 | name: "akka.persistence.cassandra.journal.TagWriters" 15 | allDeclaredFields: true 16 | } 17 | { 18 | name: "akka.persistence.cassandra.query.CassandraReadJournalProvider" 19 | methods: [{name: "", parameterTypes: ["akka.actor.ExtendedActorSystem", "com.typesafe.config.Config"]}] 20 | } 21 | { 22 | name: "akka.persistence.cassandra.snapshot.CassandraSnapshotStore" 23 | allDeclaredFields: true 24 | allDeclaredConstructors: true 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.cloudstate/cloudstate-proxy-cassandra/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.cloudstate/cloudstate-proxy-cassandra/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "io.cloudstate.proxy.cassandra.CassandraProjectionSupport" 4 | methods: [{name:"",parameterTypes: ["akka.actor.typed.ActorSystem"]}] 5 | } 6 | ] -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-buffer/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-buffer/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "io.netty.buffer.AbstractByteBufAllocator" 4 | allDeclaredMethods: true 5 | } 6 | { 7 | name: "io.netty.buffer.AbstractReferenceCountedByteBuf" 8 | fields: [{name: "refCnt"}] 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-codec/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-codec/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "io.netty.handler.codec.ByteToMessageDecoder" 4 | methods: [ 5 | {name: "channelInactive", parameterTypes: ["io.netty.channel.ChannelHandlerContext"]} 6 | {name: "channelRead", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object"]} 7 | {name: "channelReadComplete", parameterTypes: ["io.netty.channel.ChannelHandlerContext"]} 8 | {name: "userEventTriggered", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object"]} 9 | ] 10 | } 11 | { 12 | name: "io.netty.handler.codec.MessageToMessageDecoder" 13 | methods: [{name: "channelRead", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object"]}] 14 | } 15 | { 16 | name: "io.netty.handler.codec.MessageToMessageEncoder" 17 | methods: [{name: "write", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object", "io.netty.channel.ChannelPromise"]}] 18 | } 19 | ] 20 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-common/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-common/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "io.netty.util.ReferenceCountUtil" 4 | allDeclaredMethods: true 5 | } 6 | { 7 | name: "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields" 8 | fields: [{name: "producerLimit"}] 9 | } 10 | { 11 | name: "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields" 12 | fields: [{name: "consumerIndex"}] 13 | } 14 | { 15 | name: "io.netty.util.internal.shaded.org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields" 16 | fields: [{name: "producerIndex"}] 17 | } 18 | { 19 | name: "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField" 20 | fields: [{name: "consumerIndex"}] 21 | } 22 | { 23 | name: "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField" 24 | fields: [{name: "producerIndex"}] 25 | } 26 | { 27 | name: "io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField" 28 | fields: [{name: "producerLimit"}] 29 | } 30 | ] 31 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-handler/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-handler/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "io.netty.handler.timeout.IdleStateHandler" 4 | methods: [ 5 | {name: "channelActive", parameterTypes: ["io.netty.channel.ChannelHandlerContext"]} 6 | {name: "channelInactive", parameterTypes: ["io.netty.channel.ChannelHandlerContext"]} 7 | {name: "channelRead", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object"]} 8 | {name: "channelReadComplete", parameterTypes: ["io.netty.channel.ChannelHandlerContext"]} 9 | {name: "channelRegistered", parameterTypes: ["io.netty.channel.ChannelHandlerContext"]} 10 | {name: "write", parameterTypes: ["io.netty.channel.ChannelHandlerContext", "java.lang.Object", "io.netty.channel.ChannelPromise"]} 11 | ] 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/io.netty/netty-transport/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/META-INF/native-image/net.java.openjdk/base/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name":"java.lang.UnsatisfiedLinkError", 4 | "methods":[{"name":"","parameterTypes":["java.lang.String"] }] 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ["java.lang.reflect.TypeVariable"] 3 | ] 4 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/cassandra/src/graal/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":[ 3 | {"pattern":"META-INF/MANIFEST.MF"}, 4 | {"pattern":"META-INF/services/io.grpc.LoadBalancerProvider"}, 5 | {"pattern":"META-INF/services/io.grpc.NameResolverProvider"}, 6 | {"pattern":"akka-http-version.conf"}, 7 | {"pattern":"application.conf"}, 8 | {"pattern":"cloudstate-common.conf"}, 9 | {"pattern":"com/datastax/driver/core/Driver.properties"}, 10 | {"pattern":"library.properties"}, 11 | {"pattern":"org/slf4j/impl/StaticLoggerBinder.class"}, 12 | {"pattern":"reference.conf"}, 13 | {"pattern":"simplelogger.properties"}, 14 | {"pattern":"version.conf"} 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.google.protobuf/protobuf-java/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.google.protobuf/protobuf-java/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.lightbend.akka.discovery/akka-discovery-kubernetes-api/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.lightbend.akka.management/akka-management-cluster-bootstrap/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.lightbend.akka.management/akka-management-cluster-bootstrap/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.management.cluster.bootstrap.LowestAddressJoinDecider" 4 | methods: [{name: "", parameterTypes: ["akka.actor.ActorSystem", "akka.management.cluster.bootstrap.ClusterBootstrapSettings"]}] 5 | } 6 | { 7 | name: "akka.management.cluster.bootstrap.ClusterBootstrap$" 8 | fields: [{name: "MODULE$"}] 9 | } 10 | { 11 | name: "akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol$SeedNode" 12 | allDeclaredFields: true 13 | allPublicMethods: true 14 | allPublicConstructors: true 15 | } 16 | { 17 | name: "akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol$ClusterMember" 18 | allDeclaredFields: true 19 | allPublicMethods: true 20 | allPublicConstructors: true 21 | } 22 | { 23 | name: "akka.management.cluster.bootstrap.contactpoint.HttpBootstrapJsonProtocol$SeedNodes" 24 | allDeclaredFields: true 25 | allPublicMethods: true 26 | allPublicConstructors: true 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.lightbend.akka.management/akka-management/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.lightbend.akka.management/akka-management/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.management.HealthCheckRoutes" 4 | methods: [{name: "", parameterTypes: ["akka.actor.ExtendedActorSystem"]}] 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.thesamet.scalapb/scalapb-runtime/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.thesamet.scalapb/scalapb-runtime/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | # Kept on assumption it needs allDeclaredFields 3 | { 4 | name: "com.google.protobuf.any.Any" 5 | allDeclaredMethods: true 6 | allPublicMethods: true 7 | } 8 | { 9 | name: "scalapb.GeneratedMessage" 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-actor-typed/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-actor-typed/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.actor.typed.internal.adapter.ActorSystemAdapter$LoadTypedExtensions$" 4 | fields: [{name:"MODULE$"}] 5 | }, 6 | { 7 | name: "akka.actor.typed.receptionist.Receptionist$" 8 | fields: [{name:"MODULE$"}] 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-actor/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-cluster-sharding/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-cluster-sharding/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.cluster.sharding.ClusterShardingGuardian" 4 | } 5 | { 6 | name: "akka.cluster.sharding.DDataShardCoordinator" 7 | allDeclaredFields: true 8 | } 9 | { 10 | name: "akka.cluster.sharding.JoinConfigCompatCheckSharding" 11 | methods: [{name: "", parameterTypes: []}] 12 | } 13 | { 14 | name: "akka.cluster.sharding.Shard" 15 | allDeclaredFields: true 16 | } 17 | { 18 | name: "akka.cluster.sharding.ShardCoordinator" 19 | } 20 | { 21 | name: "akka.cluster.sharding.ShardCoordinator$RebalanceWorker" 22 | } 23 | { 24 | name: "akka.cluster.sharding.ShardRegion" 25 | } 26 | { 27 | name: "akka.cluster.sharding.ShardRegion$HandOffStopper" 28 | } 29 | ] 30 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-cluster-tools/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-cluster-tools/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.cluster.singleton.ClusterSingletonManager" 4 | } 5 | { 6 | name: "akka.cluster.singleton.ClusterSingletonManager$Internal$OldestChangedBuffer" 7 | } 8 | ] 9 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-cluster-typed/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-cluster-typed/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.cluster.typed.internal.receptionist.ClusterReceptionistConfigCompatChecker" 4 | methods: [{name: "", parameterTypes: []}] 5 | }, 6 | { 7 | name: "akka.cluster.typed.internal.receptionist.ClusterReceptionist$", 8 | fields: [{name:"MODULE$"}] 9 | } 10 | ] -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-cluster/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-distributed-data/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-distributed-data/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.cluster.ddata.Replicator" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-http-core/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-http-core/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.http.impl.engine.client.PoolMasterActor" 4 | } 5 | ] 6 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-http2-support/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-http2-support/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.http.scaladsl.Http2" 4 | methods: [{name: "get", parameterTypes: ["akka.actor.ActorSystem"]}] 5 | } 6 | { 7 | name: "akka.http.scaladsl.Http2Ext" 8 | methods: [{name: "bindAndHandleAsync", parameterTypes: ["scala.Function1", "java.lang.String", "int", "akka.http.scaladsl.ConnectionContext", "akka.http.scaladsl.settings.ServerSettings", "int", "akka.event.LoggingAdapter", "akka.stream.Materializer"]}] 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-persistence/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-persistence/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.persistence.journal.AsyncWriteJournal$Resequencer" 4 | } 5 | { 6 | name: "akka.persistence.journal.inmem.InmemJournal" 7 | allDeclaredFields: true 8 | allDeclaredConstructors: true 9 | } 10 | { 11 | name: "akka.persistence.RecoveryPermitter" 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-remote/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-remote/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.remote.PhiAccrualFailureDetector" 4 | methods: [{name: "", parameterTypes: ["com.typesafe.config.Config", "akka.event.EventStream"]}] 5 | } 6 | { 7 | name: "akka.remote.RemoteActorRefProvider$RemotingTerminator" 8 | allDeclaredFields: true 9 | allDeclaredConstructors: true 10 | } 11 | { 12 | name: "akka.remote.RemoteWatcher" 13 | } 14 | ] 15 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-slf4j/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-slf4j/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.event.slf4j.Slf4jLogger" 4 | methods: [{name: "", parameterTypes: []}] 5 | } 6 | { 7 | name: "akka.event.slf4j.Slf4jLoggingFilter" 8 | methods: [{name: "", parameterTypes: ["akka.actor.ActorSystem$Settings", "akka.event.EventStream"]}] 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-stream/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/akka-stream/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "akka.stream.impl.ActorRefSinkActor" 4 | allDeclaredFields: true 5 | } 6 | { 7 | name: "akka.stream.impl.StreamSupervisor" 8 | } 9 | { 10 | name: "akka.stream.SystemMaterializer$" 11 | fields: [{name: "MODULE$"}] 12 | } 13 | { 14 | name: "akka.stream.impl.fusing.ActorGraphInterpreter" 15 | allDeclaredFields: true 16 | } 17 | ] 18 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe.akka/dynamic-from-reference-conf/native-image.properties: -------------------------------------------------------------------------------- 1 | # The reflect.config.json is generated by mkDynamicAkkaReflectConfig 2 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 3 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe/ssl-config/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/com.typesafe/ssl-config/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "com.typesafe.sslconfig.ssl.NoopHostnameVerifier" 4 | allDeclaredConstructors: true 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/io.cloudstate/cloudstate-proxy-core/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/io.grpc/grpc-core/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/io.grpc/grpc-core/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "io.grpc.internal.DnsNameResolverProvider" 4 | } 5 | { 6 | name: "io.grpc.internal.JndiResourceResolverFactory" 7 | methods: [{name: "", parameterTypes: []}] 8 | } 9 | { 10 | name: "io.grpc.internal.PickFirstLoadBalancerProvider" 11 | } 12 | { 13 | name: "io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider" 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/io.grpc/grpc-netty-shaded/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/net.java.openjdk/base/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/org.agrona/agrona/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/org.agrona/agrona/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "org.agrona.concurrent.AbstractConcurrentArrayQueueConsumer" 4 | fields: [{name: "head"}] 5 | } 6 | { 7 | name: "org.agrona.concurrent.AbstractConcurrentArrayQueueProducer" 8 | fields: [ 9 | {name: "sharedHeadCache"} 10 | {name: "tail"} 11 | ] 12 | } 13 | ] 14 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/org.scala-lang/scala-library/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/core/src/graal/META-INF/native-image/org.scala-lang/scala-library/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "scala.concurrent.Future$InternalCallbackExecutor$" 4 | fields: [{name: "MODULE$"}] 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /proxy/core/src/graal/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/core/src/graal/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/core/src/graal/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/core/src/graal/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":[ 3 | {"pattern":"META-INF/MANIFEST.MF"}, 4 | {"pattern":"META-INF/services/io.grpc.LoadBalancerProvider"}, 5 | {"pattern":"META-INF/services/io.grpc.NameResolverProvider"}, 6 | {"pattern":"akka-http-version.conf"}, 7 | {"pattern":"cloudstate-common.conf"}, 8 | {"pattern":"in-memory.conf"}, 9 | {"pattern":"library.properties"}, 10 | {"pattern":"org/slf4j/impl/StaticLoggerBinder.class"}, 11 | {"pattern":"reference.conf"}, 12 | {"pattern":"simplelogger.properties"}, 13 | {"pattern":"version.conf"} 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /proxy/core/src/main/proto/cloudstate/proxy/crdt_protobufs.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // Extension for specifying which field in a message is to be considered an 16 | // entity key, for the purposes associating gRPC calls with entities and 17 | // sharding. 18 | 19 | syntax = "proto3"; 20 | 21 | package cloudstate.proxy; 22 | 23 | import "scalapb/scalapb.proto"; 24 | 25 | option java_package = "io.cloudstate.proxy.crdt.protobufs"; 26 | option (scalapb.options) = { 27 | flat_package: true 28 | }; 29 | 30 | message CrdtVote { 31 | repeated CrdtVoteEntry entries = 1; 32 | } 33 | 34 | message CrdtVoteEntry { 35 | string address = 1; 36 | sint64 uid = 2; 37 | bytes value = 3; 38 | } -------------------------------------------------------------------------------- /proxy/core/src/main/resources/dev-mode.conf: -------------------------------------------------------------------------------- 1 | # Configuration for using an in memory journal and snapshot store 2 | include classpath("in-memory.conf") 3 | 4 | cloudstate.proxy.dev-mode-enabled = true 5 | -------------------------------------------------------------------------------- /proxy/core/src/main/resources/in-memory.conf: -------------------------------------------------------------------------------- 1 | # Configuration for using an in memory journal and snapshot store 2 | include "cloudstate-common" 3 | 4 | akka.persistence { 5 | journal.plugin = inmem-journal 6 | snapshot-store.plugin = inmem-snapshot-store 7 | } 8 | 9 | inmem-journal { 10 | class = "akka.persistence.cloudstate.InmemJournal" 11 | } 12 | 13 | inmem-snapshot-store { 14 | class = "io.cloudstate.proxy.eventsourced.InMemSnapshotStore" 15 | } 16 | 17 | cloudstate.proxy { 18 | eventsourced-entity { 19 | journal-enabled = true 20 | read-journal = inmem-read-journal 21 | projection-support { 22 | enabled = true 23 | class = "io.cloudstate.proxy.eventing.InMemoryProjectionSupport" 24 | } 25 | } 26 | 27 | # Configuration for using an in-memory Value Entity persistence store 28 | value-entity { 29 | enabled = true 30 | persistence.store = "in-memory" 31 | } 32 | } 33 | 34 | inmem-read-journal { 35 | class = "akka.persistence.cloudstate.InmemReadJournal" 36 | } 37 | -------------------------------------------------------------------------------- /proxy/core/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /proxy/core/src/main/resources/no-store.conf: -------------------------------------------------------------------------------- 1 | include "cloudstate-common" 2 | 3 | # No other configuration needed, there's no journal. -------------------------------------------------------------------------------- /proxy/core/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | org.slf4j.simpleLogger.logFile=System.out 2 | org.slf4j.simpleLogger.cacheOutputStream=false 3 | org.slf4j.simpleLogger.defaultLogLevel=info 4 | org.slf4j.simpleLogger.log.io.cloudstate.proxy=debug 5 | org.slf4j.simpleLogger.log.io.cloudstate.proxy.autoscaler.KubernetesDeploymentScaler=info 6 | org.slf4j.simpleLogger.log.akka=info 7 | org.slf4j.simpleLogger.showDateTime=true 8 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS 9 | org.slf4j.simpleLogger.showThreadName=false 10 | org.slf4j.simpleLogger.showLogName=true 11 | org.slf4j.simpleLogger.showShortLogName=false 12 | org.slf4j.simpleLogger.levelInBrackets=false 13 | org.slf4j.simpleLogger.warnLevelString=WARN 14 | -------------------------------------------------------------------------------- /proxy/core/src/main/scala/akka/cloudstate/EntityStash.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package akka.cloudstate 18 | 19 | import akka.actor.{ActorRef, StashSupport} 20 | import akka.dispatch.Envelope 21 | 22 | // Access package-private akka stash methods, for custom command unstashing 23 | object EntityStash { 24 | def unstash(stash: StashSupport, message: Any, sender: ActorRef): Unit = 25 | stash.mailbox.enqueueFirst(stash.self, Envelope(message, sender, stash.context.system)) 26 | } 27 | -------------------------------------------------------------------------------- /proxy/core/src/main/scala/io/cloudstate/proxy/autoscaler/NoAutoscaler.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.proxy.autoscaler 18 | 19 | import akka.actor.Actor 20 | 21 | /** 22 | * An autoscaler that does nothing. 23 | */ 24 | class NoAutoscaler extends Actor { 25 | 26 | override def receive: Receive = { 27 | case _: AutoscalerMetrics => 28 | // Ignore 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /proxy/core/src/main/scala/io/cloudstate/proxy/crdt/UserFunctionProtocolError.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.proxy.crdt 18 | 19 | private[crdt] case class UserFunctionProtocolError(message: String) 20 | extends RuntimeException(message, null, false, false) 21 | -------------------------------------------------------------------------------- /proxy/core/src/main/scala/io/cloudstate/proxy/valueentity/store/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Value based entity support for native database. 3 | * 4 | *

Value based entities can use an implementation of {@link 5 | * io.cloudstate.proxy.valueentity.store.Repository Repository} to properly persist the entity. The {@link 6 | * io.cloudstate.proxy.valueentity.store.Repository Repository} should be provide with an implementation 7 | * of {@link io.cloudstate.proxy.valueentity.store.Store Store} to properly access the native the database or 8 | * persistence. 9 | * 10 | *

Most part of the code in this package has been copied/adapted from https://github.com/akka/akka-persistence-jdbc. 11 | */ 12 | package io.cloudstate.proxy.valueentity.store; 13 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig0.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | service IllegalHttpConfig0 { 27 | rpc fail(google.protobuf.Empty) returns (google.protobuf.Empty) { 28 | option (google.api.http) = {}; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig1.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | service IllegalHttpConfig1 { 27 | rpc fail(google.protobuf.Empty) returns (google.protobuf.Empty) { 28 | option (google.api.http) = { 29 | selector: "wrongSelector" 30 | }; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig2.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | service IllegalHttpConfig2 { 27 | rpc fail(google.protobuf.Empty) returns (google.protobuf.Empty) { 28 | option (google.api.http) = { 29 | post: "no/initial/slash" 30 | }; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig3.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | message IllegalHttpConfig3Message { 27 | repeated string illegal_repeated = 1; 28 | } 29 | 30 | service IllegalHttpConfig3 { 31 | rpc fail(IllegalHttpConfig3Message) returns (google.protobuf.Empty) { 32 | option (google.api.http) = { 33 | post: "/{illegal_repeated}" 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig4.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | message IllegalHttpConfig4Message { 27 | string duplicated = 1; 28 | } 29 | 30 | service IllegalHttpConfig4 { 31 | rpc fail(IllegalHttpConfig4Message) returns (google.protobuf.Empty) { 32 | option (google.api.http) = { 33 | post: "/{duplicated}/{duplicated}" 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig5.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | service IllegalHttpConfig5 { 27 | rpc fail(google.protobuf.Empty) returns (google.protobuf.Empty) { 28 | option (google.api.http) = { 29 | custom: { 30 | kind: "not currently supported" 31 | }; 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig6.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | service IllegalHttpConfig6 { 27 | rpc fail(google.protobuf.Empty) returns (google.protobuf.Empty) { 28 | option (google.api.http) = { 29 | get: "/foo" 30 | body: "not-available" 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig7.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | message IllegalHttpConfig7Message { 27 | repeated string not_allowed = 1; 28 | } 29 | 30 | service IllegalHttpConfig7 { 31 | rpc fail(google.protobuf.Empty) returns (google.protobuf.Empty) { 32 | option (google.api.http) = { 33 | get: "/foo" 34 | body: "not_allowed" 35 | }; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /proxy/core/src/test/proto/cloudstate/proxy/test/IllegalHttpConfig8.proto: -------------------------------------------------------------------------------- 1 | // Copyright 2019 Lightbend Inc. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | // This is the public API offered by the shopping cart entity. 16 | syntax = "proto3"; 17 | 18 | import "google/protobuf/empty.proto"; 19 | import "google/api/annotations.proto"; 20 | import "google/api/http.proto"; 21 | 22 | package cloudstate.proxy.test; 23 | 24 | option java_package = "io.cloudstate.proxy.test"; 25 | 26 | service IllegalHttpConfig8 { 27 | rpc fail(google.protobuf.Empty) returns (google.protobuf.Empty) { 28 | option (google.api.http) = { 29 | get: "/foo" 30 | response_body: "not-available" 31 | }; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /proxy/core/src/test/resources/googlepubsub.conf: -------------------------------------------------------------------------------- 1 | include "in-memory" 2 | 3 | cloudstate.proxy.eventing { 4 | support = "google-pubsub" 5 | 6 | google-pubsub { 7 | host = "localhost" 8 | port = 8085 9 | rootCa = "none" 10 | callCredentials = "none" 11 | project-id = ${?PUBSUB_PROJECT_ID} 12 | poll-interval = 1s 13 | upstream-ack-deadline = 10s 14 | downstream-batch-deadline = 5s 15 | downstream-batch-size = 10 16 | manage-topics-and-subscriptions = "by-proxy" 17 | } 18 | } -------------------------------------------------------------------------------- /proxy/core/src/test/resources/test-in-memory.conf: -------------------------------------------------------------------------------- 1 | include "in-memory" 2 | 3 | akka { 4 | coordinated-shutdown.exit-jvm = off 5 | remote.netty.tcp.port = 0 6 | } -------------------------------------------------------------------------------- /proxy/jdbc/src/main/resources/jdbc-common.conf: -------------------------------------------------------------------------------- 1 | include "cloudstate-common" 2 | 3 | cloudstate.proxy { 4 | value-entity { 5 | enabled = true 6 | persistence.store = "jdbc" 7 | } 8 | 9 | eventsourced-entity { 10 | journal-enabled = true 11 | read-journal = jdbc-read-journal 12 | projection-support { 13 | enabled = true 14 | class = "io.cloudstate.proxy.jdbc.SlickProjectionSupport" 15 | } 16 | } 17 | } 18 | 19 | akka { 20 | management.health-checks.readiness-checks { 21 | cloudstate-jdbc = "io.cloudstate.proxy.jdbc.SlickEnsureTablesExistReadyCheck" 22 | } 23 | 24 | persistence { 25 | journal.plugin = "jdbc-journal" 26 | snapshot-store.plugin = "jdbc-snapshot-store" 27 | read-journal.plugin = "jdbc-read-journal" 28 | } 29 | } 30 | 31 | akka-persistence-jdbc { 32 | shared-databases.slick.db { 33 | connectionTimeout = 5000 34 | } 35 | } 36 | 37 | jdbc-journal { 38 | use-shared-db = slick 39 | } 40 | 41 | jdbc-snapshot-store { 42 | use-shared-db = slick 43 | } 44 | 45 | jdbc-read-journal { 46 | use-shared-db = slick 47 | } 48 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/com.github.dnvriend/akka-persistence-jdbc/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/com.typesafe.slick/slick-hikaricp/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/com.typesafe.slick/slick-hikaricp/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "slick.jdbc.hikaricp.HikariCPJdbcDataSource$" 4 | fields: [{name: "MODULE$"}] 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/com.typesafe.slick/slick/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/com.typesafe.slick/slick/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "slick.jdbc.PostgresProfile$" 4 | fields: [{name: "MODULE$"}] 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/com.zaxxer/HikariCP/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/com.zaxxer/HikariCP/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "com.zaxxer.hikari.HikariConfig" 4 | allDeclaredFields: true 5 | } 6 | { 7 | name: "com.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry[]" 8 | allDeclaredConstructors: true 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/io.cloudstate/cloudstate-proxy-jdbc/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/io.cloudstate/cloudstate-proxy-jdbc/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "io.cloudstate.proxy.jdbc.SlickEnsureTablesExistReadyCheck" 4 | methods: [{name: "", parameterTypes: ["akka.actor.ActorSystem"]}] 5 | } 6 | { 7 | name: "io.cloudstate.proxy.valueentity.store.jdbc.JdbcEntityTable$Entity" 8 | allPublicMethods: true 9 | } 10 | { 11 | name: "io.cloudstate.proxy.valueentity.store.jdbc.JdbcStore" 12 | allDeclaredConstructors: true 13 | } 14 | { 15 | name: "io.cloudstate.proxy.jdbc.SlickProjectionSupport" 16 | methods: [{name:"",parameterTypes: ["akka.actor.typed.ActorSystem"]}] 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/net.java.openjdk/base/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/org.postgresql/postgresql/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json 2 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/META-INF/native-image/org.postgresql/postgresql/reflect-config.json.conf: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | name: "org.postgresql.Driver" 4 | methods: [{name: "", parameterTypes: []}] 5 | allDeclaredConstructors: true 6 | } 7 | ] 8 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ["java.sql.Connection"] 3 | ] 4 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/postgres/src/graal/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":[ 3 | {"pattern":"META-INF/MANIFEST.MF"}, 4 | {"pattern":"META-INF/services/io.grpc.LoadBalancerProvider"}, 5 | {"pattern":"META-INF/services/io.grpc.NameResolverProvider"}, 6 | {"pattern":"akka-http-version.conf"}, 7 | {"pattern":"application.conf"}, 8 | {"pattern":"cloudstate-common.conf"}, 9 | {"pattern":"jdbc-common.conf"}, 10 | {"pattern":"library.properties"}, 11 | {"pattern":"org/slf4j/impl/StaticLoggerBinder.class"}, 12 | {"pattern":"reference.conf"}, 13 | {"pattern":"simplelogger.properties"}, 14 | {"pattern":"version.conf"} 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /proxy/proxy-tests/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /proxy/spanner/src/graal/jni-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/spanner/src/graal/proxy-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/spanner/src/graal/reflect-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /proxy/spanner/src/graal/resource-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "resources":[ 3 | {"pattern":"META-INF/MANIFEST.MF"}, 4 | {"pattern":"META-INF/services/io.grpc.LoadBalancerProvider"}, 5 | {"pattern":"META-INF/services/io.grpc.NameResolverProvider"}, 6 | {"pattern":"akka-http-version.conf"}, 7 | {"pattern":"application.conf"}, 8 | {"pattern":"cloudstate-common.conf"}, 9 | {"pattern":"org/slf4j/impl/StaticLoggerBinder.class"}, 10 | {"pattern":"reference.conf"}, 11 | {"pattern":"simplelogger.properties"}, 12 | {"pattern":"version.conf"} 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /proxy/spanner/src/test/resources/application.conf: -------------------------------------------------------------------------------- 1 | akka { 2 | actor { 3 | provider = "local" 4 | } 5 | 6 | persistence.spanner { 7 | session-pool { 8 | max-size = 1 9 | } 10 | use-auth = false 11 | } 12 | 13 | grpc.client.spanner-client { 14 | host = "localhost" 15 | port = 9010 16 | use-tls = false 17 | } 18 | } 19 | 20 | cloudstate.proxy.spanner { 21 | project-id = "test" 22 | instance-id = "test-instance" 23 | } 24 | -------------------------------------------------------------------------------- /samples/README.md: -------------------------------------------------------------------------------- 1 | This directory contains projects to validate TCK(technology compatibility kit). 2 | If you are looking for real cloudstate samples, please check [here](../README.md#samples) 3 | -------------------------------------------------------------------------------- /samples/akka-client/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | // Configuration file for development 2 | 3 | akka.http.server.preview.enable-http2 = on -------------------------------------------------------------------------------- /samples/java-eventsourced-shopping-cart/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | cloudstate { 2 | system { 3 | loggers = ["akka.event.slf4j.Slf4jLogger"] 4 | loglevel = "DEBUG" 5 | logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" 6 | } 7 | } -------------------------------------------------------------------------------- /samples/java-eventsourced-shopping-cart/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | org.slf4j.simpleLogger.logFile=System.out 2 | org.slf4j.simpleLogger.cacheOutputStream=false 3 | org.slf4j.simpleLogger.defaultLogLevel=debug 4 | org.slf4j.simpleLogger.log.io.cloudstate.javasupport=debug 5 | org.slf4j.simpleLogger.log.io.cloudstate=debug 6 | org.slf4j.simpleLogger.log.akka=debug 7 | org.slf4j.simpleLogger.showDateTime=true 8 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS 9 | org.slf4j.simpleLogger.showThreadName=false 10 | org.slf4j.simpleLogger.showLogName=true 11 | org.slf4j.simpleLogger.showShortLogName=false 12 | org.slf4j.simpleLogger.levelInBrackets=false 13 | org.slf4j.simpleLogger.warnLevelString=WARN 14 | -------------------------------------------------------------------------------- /samples/java-pingpong/src/main/java/io/cloudstate/samples/pingpong/Main.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.samples.pingpong; 18 | 19 | import io.cloudstate.javasupport.CloudState; 20 | import io.cloudstate.pingpong.Pingpong; 21 | 22 | public final class Main { 23 | public static final void main(String[] args) throws Exception { 24 | new CloudState() 25 | .registerEventSourcedEntity( 26 | PingPongEntity.class, 27 | Pingpong.getDescriptor().findServiceByName("PingPongService"), 28 | Pingpong.getDescriptor()) 29 | .start() 30 | .toCompletableFuture() 31 | .get(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /samples/java-pingpong/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | cloudstate { 2 | system { 3 | loggers = ["akka.event.slf4j.Slf4jLogger"] 4 | loglevel = "DEBUG" 5 | logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" 6 | } 7 | } -------------------------------------------------------------------------------- /samples/java-pingpong/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | org.slf4j.simpleLogger.logFile=System.out 2 | org.slf4j.simpleLogger.cacheOutputStream=false 3 | org.slf4j.simpleLogger.defaultLogLevel=debug 4 | org.slf4j.simpleLogger.log.io.cloudstate.javasupport=debug 5 | org.slf4j.simpleLogger.log.io.cloudstate=debug 6 | org.slf4j.simpleLogger.log.akka=debug 7 | org.slf4j.simpleLogger.showDateTime=true 8 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS 9 | org.slf4j.simpleLogger.showThreadName=false 10 | org.slf4j.simpleLogger.showLogName=true 11 | org.slf4j.simpleLogger.showShortLogName=false 12 | org.slf4j.simpleLogger.levelInBrackets=false 13 | org.slf4j.simpleLogger.warnLevelString=WARN 14 | -------------------------------------------------------------------------------- /samples/java-shopping-cart/src/main/java/io/cloudstate/samples/shoppingcart/Main.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.samples.shoppingcart; 18 | 19 | import com.example.valueentity.shoppingcart.Shoppingcart; 20 | import io.cloudstate.javasupport.CloudState; 21 | 22 | public final class Main { 23 | public static final void main(String[] args) throws Exception { 24 | new CloudState() 25 | .registerEntity( 26 | ShoppingCartEntity.class, 27 | Shoppingcart.getDescriptor().findServiceByName("ShoppingCart"), 28 | com.example.valueentity.shoppingcart.persistence.Domain.getDescriptor()) 29 | .start() 30 | .toCompletableFuture() 31 | .get(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /samples/java-shopping-cart/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | cloudstate { 2 | system { 3 | loggers = ["akka.event.slf4j.Slf4jLogger"] 4 | loglevel = "DEBUG" 5 | logging-filter = "akka.event.slf4j.Slf4jLoggingFilter" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /samples/java-shopping-cart/src/main/resources/simplelogger.properties: -------------------------------------------------------------------------------- 1 | org.slf4j.simpleLogger.logFile=System.out 2 | org.slf4j.simpleLogger.cacheOutputStream=false 3 | org.slf4j.simpleLogger.defaultLogLevel=debug 4 | org.slf4j.simpleLogger.log.io.cloudstate.javasupport=debug 5 | org.slf4j.simpleLogger.log.io.cloudstate=debug 6 | org.slf4j.simpleLogger.log.akka=debug 7 | org.slf4j.simpleLogger.showDateTime=true 8 | org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS 9 | org.slf4j.simpleLogger.showThreadName=false 10 | org.slf4j.simpleLogger.showLogName=true 11 | org.slf4j.simpleLogger.showShortLogName=false 12 | org.slf4j.simpleLogger.levelInBrackets=false 13 | org.slf4j.simpleLogger.warnLevelString=WARN 14 | -------------------------------------------------------------------------------- /samples/js-crdts/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /samples/js-crdts/.nvmrc: -------------------------------------------------------------------------------- 1 | v12 2 | -------------------------------------------------------------------------------- /samples/js-crdts/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | require("./crdt-example").start(); 18 | -------------------------------------------------------------------------------- /samples/js-crdts/presence-client.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/samples/js-crdts/presence-client.js -------------------------------------------------------------------------------- /samples/js-crdts/stateful-service.yaml: -------------------------------------------------------------------------------- 1 | # Deployment spec for our CRDT examples 2 | apiVersion: cloudstate.io/v1alpha1 3 | kind: StatefulService 4 | metadata: 5 | name: crdts 6 | spec: 7 | containers: 8 | - image: cloudstateio/js-crdts:latest 9 | -------------------------------------------------------------------------------- /samples/js-crdts/user-function.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/samples/js-crdts/user-function.desc -------------------------------------------------------------------------------- /samples/js-shopping-cart-load-generator/load-generator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: load-generator 5 | spec: 6 | replicas: &replicas 1 7 | strategy: 8 | type: Recreate 9 | selector: 10 | matchLabels: 11 | app: load-generator 12 | template: 13 | metadata: 14 | labels: 15 | app: load-generator 16 | spec: 17 | containers: 18 | - name: generator 19 | image: gcr.io/stateserv/js-shopping-cart-load-generator:latest 20 | 21 | env: 22 | - name: NUM_USERS 23 | value: "100" 24 | - name: REQUEST_RATE_PER_S 25 | value: "200" 26 | - name: RAMP_UP_S 27 | value: "20" 28 | - name: SHOPPING_CART_SERVICE 29 | value: "shopping-cart.default.svc.cluster.local" 30 | - name: SHOPPING_CART_SERVICE_PORT 31 | value: "80" 32 | - name: READ_WRITE_REQUEST_RATIO 33 | value: "1.0" 34 | - name: MAX_RESPONSE_LAG_MS 35 | value: "2000" 36 | - name: JAVA_OPTS 37 | value: "-Xms128m -Xmx128m" 38 | 39 | resources: 40 | limits: 41 | memory: 256Mi 42 | requests: 43 | cpu: 0.25 44 | memory: 256Mi 45 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/.nvmrc: -------------------------------------------------------------------------------- 1 | v12 2 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/cassandra-store.yaml: -------------------------------------------------------------------------------- 1 | # Deployment spec for a store. A store is a logical abstraction over a database 2 | # deployment, and captures how to deploy and connect to that database. Multiple 3 | # StatefulServices's would use a single store. 4 | apiVersion: cloudstate.io/v1alpha1 5 | kind: StatefulStore 6 | metadata: 7 | name: cassandra 8 | spec: 9 | 10 | # This is a Cassandra deployment, so supply configuration for Cassandra. 11 | cassandra: 12 | 13 | # The host name of the Cassandra service to connect to. 14 | service: cassandra-cassandra-0.cassandra-cassandra-svc.cassandra.svc.cluster.local 15 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/in-memory-store.yaml: -------------------------------------------------------------------------------- 1 | # Deployment spec for a store. A store is a logical abstraction over a database 2 | # deployment, and captures how to deploy and connect to that database. Multiple 3 | # StatefulService's would use a single store. 4 | apiVersion: cloudstate.io/v1alpha1 5 | kind: StatefulStore 6 | metadata: 7 | name: inmemory 8 | labels: 9 | foo: bar 10 | spec: 11 | inMemory: true 12 | 13 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | const CloudState = require("cloudstate").CloudState; 18 | 19 | const server = new CloudState(); 20 | server.addEntity(require("./shoppingcart")); 21 | 22 | server.start(); -------------------------------------------------------------------------------- /samples/js-shopping-cart/istio.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: Gateway 3 | metadata: 4 | name: gateway 5 | spec: 6 | selector: 7 | istio: ingressgateway 8 | servers: 9 | - port: 10 | number: 8000 11 | name: tcp 12 | protocol: tcp 13 | hosts: 14 | - "*" 15 | --- 16 | apiVersion: networking.istio.io/v1alpha3 17 | kind: VirtualService 18 | metadata: 19 | name: shopping-cart-route 20 | spec: 21 | hosts: 22 | - "*" 23 | gateways: 24 | - gateway 25 | tcp: 26 | - match: 27 | - port: 8000 28 | route: 29 | - destination: 30 | port: 31 | number: 80 32 | host: shopping-cart 33 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/js-shopping-cart.yaml: -------------------------------------------------------------------------------- 1 | # Deployment spec for our shopping cart event sourced function 2 | apiVersion: cloudstate.io/v1alpha1 3 | kind: StatefulService 4 | metadata: 5 | name: shopping-cart 6 | spec: 7 | 8 | # Datastore configuration 9 | storeConfig: 10 | statefulStore: 11 | # Name of a deployed Datastore to use. 12 | name: inmemory 13 | 14 | containers: 15 | - image: cloudstateio/samples-js-shopping-cart:latest 16 | name: user-function 17 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/knative.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: serving.knative.dev/v1alpha1 2 | kind: Service 3 | metadata: 4 | name: shopping-cart 5 | spec: 6 | template: 7 | metadata: 8 | annotations: 9 | force-upgrade: one 10 | spec: 11 | containers: 12 | - image: cloudstateio/js-shopping-cart:latest 13 | ports: 14 | - name: h2c 15 | containerPort: 8080 16 | deployer: 17 | name: CloudState 18 | config: 19 | # Journal configuration 20 | journal: 21 | 22 | # Name of a deployed EventSourcedJournal to use, must match the name configured above. 23 | # A namespace might also be specified. 24 | name: cassandra 25 | 26 | # Journal specific configuration 27 | config: 28 | 29 | # Since the journal is a Cassandra journal, we need to specify the keyspace to use. 30 | keyspace: shoppingcart 31 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/postgres-store.yaml: -------------------------------------------------------------------------------- 1 | # Deployment spec for a store. A store is a logical abstraction over a database 2 | # deployment, and captures how to deploy and connect to that database. Multiple 3 | # StatefulServices's would use a single store. 4 | apiVersion: cloudstate.io/v1alpha1 5 | kind: StatefulStore 6 | metadata: 7 | name: postgres 8 | spec: 9 | 10 | # Configuration for a postgres store 11 | type: Postgres 12 | 13 | # The name of the unmanaged Postgres service to connect to. 14 | host: postgresql-postgresql-svc.postgresql.svc.cluster.local 15 | 16 | # The credentials for connecting to Postgres 17 | credentials: 18 | 19 | # The secret to consume the credentials from 20 | secret: 21 | name: postgres-shopping-cart 22 | 23 | # By default, the database, username and password will be read from fields in the 24 | # secret with the keys database, username and password respectively. If your 25 | # secret uses different keys, eg, db, user and pass, they can be customized 26 | # as shown below: 27 | 28 | # databaseKey = db 29 | # usernameKey = user 30 | # passwordKey = pass 31 | 32 | -------------------------------------------------------------------------------- /samples/js-shopping-cart/user-function.desc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudstateio/cloudstate/82207cbc1830f585b0484f5ea9891bdc488add81/samples/js-shopping-cart/user-function.desc -------------------------------------------------------------------------------- /tck/src/it/resources/reference.conf: -------------------------------------------------------------------------------- 1 | cloudstate-tck { 2 | #verify is a list of names of combinations to run for the TCK 3 | verify = [] 4 | #combinations is a list of config objects with a name, a proxy, and a service 5 | combinations = [] 6 | 7 | tck { 8 | hostname = "127.0.0.1" 9 | hostname = ${?HOST} 10 | port = 8090 11 | } 12 | 13 | proxy { 14 | hostname = "127.0.0.1" 15 | hostname = ${?HOST} 16 | port = 9000 17 | directory = ${user.dir} 18 | pre-command = [] 19 | command = [] 20 | stop-command = [] 21 | env-vars { 22 | } 23 | # If specified, will start a docker container, with the environment variable USER_FUNCTION_HOST set to the host 24 | # to connect to, USER_FUNCTION_PORT set to the port to connect to, and HTTP_PORT set to the port above. 25 | docker-image = "" 26 | docker-pull = false 27 | docker-args = [] 28 | } 29 | 30 | service { 31 | hostname = "127.0.0.1" 32 | hostname = ${?HOST} 33 | port = 8080 34 | directory = ${user.dir} 35 | pre-command = [] 36 | command = [] 37 | stop-command = [] 38 | env-vars { 39 | } 40 | # If specified, will start a docker container, with the environment variable PORT set to the port above. 41 | docker-image = "" 42 | docker-pull = true 43 | docker-args = [] 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tck/src/main/resources/reference.conf: -------------------------------------------------------------------------------- 1 | cloudstate.tck { 2 | hostname = "0.0.0.0" 3 | hostname = ${?TCK_HOST} 4 | port = 8090 5 | port = ${?TCK_PORT} 6 | 7 | proxy { 8 | hostname = "127.0.0.1" 9 | hostname = ${?TCK_PROXY_HOST} 10 | port = 9000 11 | port = ${?TCK_PROXY_PORT} 12 | } 13 | 14 | service { 15 | hostname = "127.0.0.1" 16 | hostname = ${?TCK_SERVICE_HOST} 17 | port = 8080 18 | port = ${?TCK_SERVICE_PORT} 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /testkit/src/main/scala/io/cloudstate/testkit/Sockets.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Lightbend Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package io.cloudstate.testkit 18 | 19 | object Sockets { 20 | // We were using akka.testkit.SocketUtil.temporaryLocalPort but that is broken 21 | // in akka 2.6.9 (and will be fixed by https://github.com/akka/akka/pull/29607). 22 | def temporaryLocalPort(): Int = { 23 | val address = new java.net.InetSocketAddress("localhost", 0) 24 | val socket = java.nio.channels.ServerSocketChannel.open().socket() 25 | try { 26 | socket.bind(address) 27 | socket.getLocalPort 28 | } finally socket.close() 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /travis/jvmopts: -------------------------------------------------------------------------------- 1 | -XX:+UseCompressedOops 2 | -XX:+CMSClassUnloadingEnabled 3 | -Dfile.encoding=UTF8 -------------------------------------------------------------------------------- /travis/upload-release-assets.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Upload release assets to Github 4 | # 5 | # Expects that the release already exists in Github 6 | # Requires a GITHUB_TOKEN for authorization, and a current TRAVIS_TAG 7 | # Requires `jq` to be installed in the Travis build 8 | 9 | set -e 10 | 11 | readonly tag="$TRAVIS_TAG" 12 | readonly token="$GITHUB_TOKEN" 13 | 14 | readonly script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd -P)" 15 | readonly base_dir="$(cd "$script_dir/.." && pwd)" 16 | 17 | readonly owner="cloudstateio" 18 | readonly repo="cloudstate" 19 | readonly version="${tag:1}" 20 | 21 | readonly release_url="https://api.github.com/repos/$owner/$repo/releases/tags/$tag" 22 | readonly release_id=$(curl -s $release_url | jq -r .id) 23 | readonly auth_header="Authorization: token $token" 24 | 25 | readonly -a assets=( 26 | "$base_dir/operator/cloudstate-$version.yaml" 27 | "$base_dir/protocols/target/cloudstate-protocols-$version.zip" 28 | "$base_dir/protocols/target/cloudstate-tck-protocols-$version.zip" 29 | ) 30 | 31 | for asset in "${assets[@]}"; do 32 | asset_url="https://uploads.github.com/repos/$owner/$repo/releases/$release_id/assets?name=$(basename $asset)" 33 | curl -H "$auth_header" -H "Content-Type: application/octet-stream" --data-binary @"$asset" $asset_url 34 | done 35 | --------------------------------------------------------------------------------